小学四则运算练习题生成器 - 结对编程作业
作者
学生1学号:2352521
学生2学号:2352619
本作业主要由学生1完成,学生2辅助。
作业要求
根据第8周PPT的要求,我们需要开发一个能生成300道四则运算练习题的程序,要求:
- 包含两个运算符
- 数字在100以内
- 不需要写答案(但程序需要能检查答案)
- 答案在0-1000之间
- 以结对编程方式完成
开发过程
我们采用了结对编程的方式完成本次作业,具体过程如下:
我们首先仔细阅读了PPT中的需求,明确了程序需要实现的功能,讨论了是否需要支持括号运算(决定支持),确定了运算符的优先级处理方式,然后决定了程序的基本结构,确定了使用枚举类型表示运算符,之后就开始编写代码,首先学生1负责编写核心计算逻辑,学生2负责审核,然后再角色互换,在完成了所有的代码后,我们共同调试和测试了程序。
结果:
我们采用了输出一道题目完成一道题目的形式完成代码,每当你做完一道题时,程序会输出正确或是错误,如果做题人做错了题目,还会接着输出正确的结果和做题过程,让做题人更加容易理解。
![]()
而在做完所有的题目之后,我们还会输出本次做题的正确率,让做题人更加直接地了解到自己本次的训练情况。
![image]()
下面是我们代码的功能说明
题目生成:随机生成包含两个运算符的四则运算题,随机决定是否添加括号,确保数字在100以内,确保答案在0-1000之间且为整数。
答案检查:答错时显示正确答案和详细计算过程
统计功能:记录答题总数和正确数,计算并显示正确率
结对编程作业总结
通过这次小学四则运算练习题生成器的结对编程实践,我们对这种开发模式有了深刻的认识和体会。在为期一周的开发过程中,我们两人密切配合,共同完成了从需求分析到最终实现的全部工作。
在技术层面,我们成功实现了一个功能完整的四则运算题目生成系统。系统能够智能处理运算符优先级和括号运算,自动规避除数为零等异常情况,并确保所有题目答案都在合理范围内。特别值得一提的是,当用户回答错误时,系统会详细展示运算步骤,这个教学功能得到了我们的一致好评。通过这次实践,我们不仅巩固了C++编程技能,更深入理解了表达式求值算法的实现原理。
在协作方面,结对编程模式展现出独特的优势。开发过程中,一个人的编码思路可能会陷入局限,而另一个人的实时审核和建议往往能带来突破。例如在处理运算符优先级时,正是通过两人的反复讨论,我们才找到了最优的实现方案。角色轮换的机制也让双方都能从不同角度理解整个项目,避免了知识盲区的出现。当然,这种模式也需要良好的沟通和耐心,特别是在出现意见分歧时,我们学会了通过理性分析和技术验证来达成共识。
这次作业也让我们认识到一些需要改进的地方。例如,在初期我们对需求的理解不够透彻,导致部分功能需要返工;代码注释的规范性也有待加强。这些经验教训将指导我们在未来的项目中做得更好。
以上便是本次作业的全部内容,源代码为:``
点击查看代码
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <sstream>
#include <vector>
#include <string>
#include <set>
using namespace std;
// 定义运算符类型
enum OperatorType {
ADD, SUB, MUL, DIV
};
// 将运算符枚举转换为字符
char getOperatorChar(OperatorType op) {
switch (op) {
case ADD: return '+';
case SUB: return '-';
case MUL: return '*';
case DIV: return '/';
default: return '+';
}
}
// 计算表达式结果
double calculateResult(int a, OperatorType op1, int b, OperatorType op2, int c, bool hasBracket) {
double result = 0;
if (hasBracket) {
// 有括号的情况,括号内的运算先进行
double temp = 0;
if (op2 == ADD) {
temp = b + c;
} else if (op2 == SUB) {
temp = b - c;
} else if (op2 == MUL) {
temp = b * c;
} else {
// 除法需要检查除数是否为0
if (c == 0) return -1; // 表示无效结果
temp = (double)b / c;
}
// 计算括号外的运算
if (op1 == ADD) {
result = a + temp;
} else if (op1 == SUB) {
result = a - temp;
} else if (op1 == MUL) {
result = a * temp;
} else {
// 除法需要检查除数是否为0
if (temp == 0) return -1; // 表示无效结果
result = (double)a / temp;
}
} else {
// 无括号的情况,按照运算符优先级计算
if (op1 == MUL || op1 == DIV) {
// 第一个运算符优先级高
double temp = 0;
if (op1 == MUL) {
temp = a * b;
} else {
// 除法需要检查除数是否为0
if (b == 0) return -1; // 表示无效结果
temp = (double)a / b;
}
// 计算第二个运算
if (op2 == ADD) {
result = temp + c;
} else if (op2 == SUB) {
result = temp - c;
} else if (op2 == MUL) {
result = temp * c;
} else {
// 除法需要检查除数是否为0
if (c == 0) return -1; // 表示无效结果
result = temp / c;
}
} else if (op2 == MUL || op2 == DIV) {
// 第二个运算符优先级高
double temp = 0;
if (op2 == MUL) {
temp = b * c;
} else {
// 除法需要检查除数是否为0
if (c == 0) return -1; // 表示无效结果
temp = (double)b / c;
}
// 计算第一个运算
if (op1 == ADD) {
result = a + temp;
} else {
result = a - temp;
}
} else {
// 两个运算符优先级相同,从左到右计算
double temp = 0;
if (op1 == ADD) {
temp = a + b;
} else {
temp = a - b;
}
if (op2 == ADD) {
result = temp + c;
} else {
result = temp - c;
}
}
}
return result;
}
// 生成一道题目
string generateQuestion(int& answer, bool& hasBracket, int& a, int& b, int& c, OperatorType& op1, OperatorType& op2) {
double result;
do {
// 生成100以内的随机数
a = rand() % 100 + 1;
b = rand() % 100 + 1;
c = rand() % 100 + 1;
// 生成随机运算符
op1 = (OperatorType)(rand() % 4);
op2 = (OperatorType)(rand() % 4);
// 随机决定是否添加括号
hasBracket = (rand() % 2 == 0);
// 计算结果
result = calculateResult(a, op1, b, op2, c, hasBracket);
// 检查结果是否有效且在0-1000范围内
} while (result < 0 || result > 1000 || result != (int)result);
// 设置答案
answer = (int)result;
// 构造题目字符串
string question;
if (hasBracket) {
stringstream ss;
ss << a << " " << getOperatorChar(op1) << " ("
<< b << " " << getOperatorChar(op2) << " "
<< c << ") = ";
question = ss.str();
} else {
stringstream ss;
ss << a << " " << getOperatorChar(op1) << " "
<< b << " " << getOperatorChar(op2) << " "
<< c << " = ";
question = ss.str();
}
return question;
}
int main() {
// 初始化随机数生成器
srand(time(NULL));
cout << "小学四则运算练习题(共300题)" << endl;
cout << "请回答每道题目,输入答案后按回车键。" << endl;
cout << "======================================" << endl << endl;
int totalQuestions = 300;
int correctCount = 0;
for (int i = 0; i < totalQuestions; i++) {
int answer;
bool hasBracket;
int a, b, c;
OperatorType op1, op2;
string question = generateQuestion(answer, hasBracket, a, b, c, op1, op2);
cout << i + 1 << ". " << question;
int userAnswer;
cin >> userAnswer;
if (userAnswer == answer) {
cout << "正确!" << endl << endl;
correctCount++;
} else {
cout << "错误!正确答案是:" << answer << endl;
// 解释计算过程
cout << "计算过程:";
if (hasBracket) {
double bracketResult;
if (op2 == ADD) {
bracketResult = b + c;
cout << "先计算括号内 " << b << " + " << c << " = " << bracketResult << endl;
} else if (op2 == SUB) {
bracketResult = b - c;
cout << "先计算括号内 " << b << " - " << c << " = " << bracketResult << endl;
} else if (op2 == MUL) {
bracketResult = b * c;
cout << "先计算括号内 " << b << " * " << c << " = " << bracketResult << endl;
} else {
bracketResult = (double)b / c;
cout << "先计算括号内 " << b << " / " << c << " = " << bracketResult << endl;
}
cout << "然后计算 " << a << " " << getOperatorChar(op1) << " " << bracketResult << " = " << answer << endl << endl;
} else {
if (op1 == MUL || op1 == DIV || (op1 == ADD || op1 == SUB) && (op2 == ADD || op2 == SUB)) {
double firstResult;
if (op1 == ADD) {
firstResult = a + b;
cout << "先计算 " << a << " + " << b << " = " << firstResult << endl;
} else if (op1 == SUB) {
firstResult = a - b;
cout << "先计算 " << a << " - " << b << " = " << firstResult << endl;
} else if (op1 == MUL) {
firstResult = a * b;
cout << "先计算 " << a << " * " << b << " = " << firstResult << endl;
} else {
firstResult = (double)a / b;
cout << "先计算 " << a << " / " << b << " = " << firstResult << endl;
}
cout << "然后计算 " << firstResult << " " << getOperatorChar(op2) << " " << c << " = " << answer << endl << endl;
} else {
double secondResult;
if (op2 == MUL) {
secondResult = b * c;
cout << "先计算 " << b << " * " << c << " = " << secondResult << endl;
} else {
secondResult = (double)b / c;
cout << "先计算 " << b << " / " << c << " = " << secondResult << endl;
}
cout << "然后计算 " << a << " " << getOperatorChar(op1) << " " << secondResult << " = " << answer << endl << endl;
}
}
}
}
cout << "练习完成!" << endl;
cout << "总题数:" << totalQuestions << ",正确数:" << correctCount << endl;
cout << "正确率:" << (double)correctCount / totalQuestions * 100 << "%" << endl;
return 0;
}


浙公网安备 33010602011771号