項目介紹
項目引言
在學(xué)習(xí)編程的道路上,理論知識與實踐項目相輔相成,而結(jié)對編程更是加速成長、深化理解的有效方式,對于兩個可能編程風(fēng)格和速度截然不同的人,想要共同完成一個項目就不得不需要溝通、設(shè)計和互相借鑒學(xué)習(xí)。近期,我與搭檔(學(xué)號2352313)攜手合作,共同完成了一個 C++ 編寫的四則運算測驗程序。通過兩人思維的碰撞與技術(shù)的互補,我們不僅鞏固了 C++ 編程的各類知識,還收獲了團(tuán)隊協(xié)作的寶貴經(jīng)驗。該程序能夠生成包含兩個運算符的四則運算題目,引導(dǎo)用戶進(jìn)行答題,并在測驗結(jié)束后給出得分與個性化評價,是一個兼具實用性與學(xué)習(xí)價值的小項目。接下來,我將詳細(xì)分享我們在結(jié)對編程過程中的設(shè)計思路、代碼實現(xiàn)與實踐感悟 。
功能需求
1.能夠隨機生成包含兩個運算符的四則運算題目,運算符包括加、減、乘、除。
2.確保生成的題目符合數(shù)學(xué)規(guī)則,例如除數(shù)不能為零,減法結(jié)果不能為負(fù)數(shù),除法結(jié)果必須為整數(shù)。
3.能夠讓用戶輸入答案,并判斷答案是否正確。
4.記錄用戶的正確答題數(shù)量,并計算得分。
5.根據(jù)用戶的得分給出相應(yīng)的評價。
用戶需求
1.在學(xué)校教育體系中,四則運算是數(shù)學(xué)學(xué)科最基礎(chǔ)且重要的內(nèi)容。小學(xué)階段,學(xué)生需要通過大量練習(xí)來熟練掌握整數(shù)的加減乘除運算,打好數(shù)學(xué)基礎(chǔ);初中階段,運算的復(fù)雜性提升,包含小數(shù)、分?jǐn)?shù)等類型,對運算的準(zhǔn)確性和速度都有更高要求。此程序可以為學(xué)生提供個性化的練習(xí)方式,學(xué)生通過輸入題目數(shù)量,能夠自主安排學(xué)習(xí)強度,在課后進(jìn)行針對性的訓(xùn)練,從而提高課堂知識的掌握程度,在考試中取得更好成績。同時,程序即時反饋答案正誤和最終得分評價的功能,能讓學(xué)生快速了解自己的學(xué)習(xí)效果,及時發(fā)現(xiàn)知識薄弱點。
2.教師在教學(xué)過程中,常常需要為學(xué)生布置適量的四則運算練習(xí)題。傳統(tǒng)方式下,教師需要手動編寫題目,耗時耗力。使用本程序,教師可以根據(jù)教學(xué)進(jìn)度和學(xué)生的實際水平,輸入合適的題目數(shù)量,快速生成大量符合要求的四則運算題目,用于課堂練習(xí)、課后作業(yè)或測驗。而且,程序統(tǒng)一的評分和評價標(biāo)準(zhǔn),也能為教師評估學(xué)生學(xué)習(xí)情況提供參考,減輕教師的教學(xué)負(fù)擔(dān),提高教學(xué)效率。
3.家長在輔導(dǎo)孩子學(xué)習(xí)四則運算時,往往缺乏系統(tǒng)的練習(xí)資源。借助這個程序,家長可以根據(jù)孩子的學(xué)習(xí)狀態(tài)和能力,靈活調(diào)整題目數(shù)量,為孩子制定專屬的學(xué)習(xí)計劃。在孩子完成練習(xí)后,家長能夠通過程序給出的得分和評價,直觀了解孩子的學(xué)習(xí)效果,有針對性地進(jìn)行輔導(dǎo)和強化訓(xùn)練,助力孩子提升數(shù)學(xué)運算能力。
設(shè)計思路
整體架構(gòu)
數(shù)據(jù)結(jié)構(gòu)
使用 std::mt19937 作為隨機數(shù)生成器,確保生成的隨機數(shù)具有較好的隨機性。
使用 std::vector<char> 存儲運算符,方便隨機選擇運算符。
使用 std::stringstream 來拼接題目字符串。
算法設(shè)計
隨機數(shù)生成:使用 std::uniform_int_distribution 生成 1 到 100 之間的隨機整數(shù)。
題目生成:通過循環(huán)不斷生成隨機的運算符和操作數(shù),直到生成的題目符合數(shù)學(xué)規(guī)則和結(jié)果范圍要求。
結(jié)果計算:根據(jù)運算符的優(yōu)先級,先計算乘法和除法,再計算加法和減法。
代碼實現(xiàn)
代碼設(shè)計
以下是該項目的代碼設(shè)計:
#include <iostream>
#include <string>
#include <vector>
#include <random>
#include <ctime>
#include <stdexcept>
#include <sstream>
#include <iomanip>
#include <limits>
class MathQuiz {
private:
std::mt19937 rng;
const std::vector<char> operators{ '+', '-', '*', '/' };
int randomNum() {
std::uniform_int_distribution<int> dist(1, 100);
return dist(rng);
}
bool isDivisible(int a, int b) {
return (b != 0) && (a % b == 0);
}
int calculateResult(int num1, char op1, int num2, char op2, int num3) {
int part1, part2, result;
if ((op1 == '+' || op1 == '-') && (op2 == '*' || op2 == '/')) {
part2 = (op2 == '*') ? num2 * num3 : num2 / num3;
result = (op1 == '+') ? num1 + part2 : num1 - part2;
}
else {
switch (op1) {
case '+': part1 = num1 + num2; break;
case '-': part1 = num1 - num2; break;
case '*': part1 = num1 * num2; break;
case '/': part1 = num1 / num2; break;
}
switch (op2) {
case '+': result = part1 + num3; break;
case '-': result = part1 - num3; break;
case '*': result = part1 * num3; break;
case '/': result = part1 / num3; break;
}
}
return result;
}
public:
MathQuiz() {
rng.seed(std::time(nullptr));
}
// 修改了返回類型,避免使用結(jié)構(gòu)化綁定
void generateProblem(std::string& problem, int& answer) {
int num1, num2, num3;
char op1, op2;
bool valid;
do {
valid = true;
std::uniform_int_distribution<int> opDist(0, 3);
op1 = operators[opDist(rng)];
op2 = operators[opDist(rng)];
num1 = randomNum();
num2 = randomNum();
num3 = randomNum();
if (op1 == '/' && !isDivisible(num1, num2)) {
valid = false;
continue;
}
if (op2 == '/') {
if (op1 == '+' || op1 == '-') {
int temp = (op1 == '+') ? num1 + num2 : num1 - num2;
if (!isDivisible(temp, num3)) {
valid = false;
continue;
}
}
else {
if (!isDivisible(num2, num3)) {
valid = false;
continue;
}
}
}
if (op1 == '-' && num1 < num2) {
valid = false;
continue;
}
if (op2 == '-') {
if (op1 == '+' || op1 == '-') {
int temp = (op1 == '+') ? num1 + num2 : num1 - num2;
if (temp < num3) {
valid = false;
continue;
}
}
else {
if (num2 < num3) {
valid = false;
continue;
}
}
}
answer = calculateResult(num1, op1, num2, op2, num3);
if (answer < 0 || answer > 1000) {
valid = false;
}
} while (!valid);
std::stringstream ss;
ss << num1 << " " << op1 << " " << num2 << " " << op2 << " " << num3;
problem = ss.str();
}
void runQuiz(int numProblems) {
int correctAnswers = 0;
std::cout << "\n四則運算測驗開始!共 " << numProblems << " 題。\n\n";
for (int i = 0; i < numProblems; ++i) {
std::string problem;
int answer;
generateProblem(problem, answer); // 修改了調(diào)用方式
int userAnswer;
std::cout << "第 " << i + 1 << " 題: " << problem << " = ? ";
while (!(std::cin >> userAnswer)) {
std::cout << "請輸入一個有效的整數(shù): ";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cin.ignore(); // 清除換行符
if (userAnswer == answer) {
std::cout << "? 正確!\n";
correctAnswers++;
}
else {
std::cout << "? 錯誤!正確答案是: " << answer << "\n";
}
std::cout << std::endl;
}
double score = static_cast<double>(correctAnswers) / numProblems * 100;
std::cout << "測驗結(jié)束!\n";
std::cout << "你的得分: " << correctAnswers << "/" << numProblems
<< " (" << std::fixed << std::setprecision(1) << score << "%)\n";
if (score == 100) {
std::cout << "六百六十六你真的會做\n";
}
else if (score >= 80) {
std::cout << "有點東西,但不多\n";
}
else if (score >= 60) {
std::cout << "一般\n";
}
else {
std::cout << "純飛舞,菜就多練\n";
}
}
};
int main() {
MathQuiz quiz;
int numProblems;
std::cout << "四則運算練習(xí)題與測驗系統(tǒng)\n";
std::cout << "請輸入要回答的題目數(shù)量: ";
std::cin >> numProblems;
if (std::cin.fail() || numProblems <= 0) {
std::cerr << "請輸入一個有效的正整數(shù)" << std::endl;
return 1;
}
quiz.runQuiz(numProblems);
return 0;
}







浙公網(wǎng)安備 33010602011771號