结对编码
本次结对编码是由我和2352437同学共同完成 主题是完成四则运算的编码设计
项目背景:在我们平时的学习和教学中,经常需要为学生提供大量的数学题目进行练习。然而,手动生成这些题目不仅耗时耗力,而且难以保证题目的随机性和多样性。为了简化这个过程,我们决定编写一个程序,自动生成四则运算的题目,并确保它们符合一定的范围要求(即操作数在1到100之间,答案在0到1000之间)。
结果截图:
主要代码:
点击查看代码
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <string>
#include <stack>
#include <set>
#include <cmath>
using namespace std;
// 得分系统结构体
struct ScoreSystem {
int totalProblems = 0;
int correctAnswers = 0;
int wrongAnswers = 0;
double score = 0.0;
void addCorrect() {
correctAnswers++;
totalProblems++;
calculateScore();
}
void addWrong() {
wrongAnswers++;
totalProblems++;
calculateScore();
}
void calculateScore() {
if (totalProblems > 0) {
score = round((double)correctAnswers / totalProblems * 100);
}
}
void displayStats() {
cout << "\n===== 答题统计 =====" << endl;
cout << "总题数: " << totalProblems << endl;
cout << "正确: " << correctAnswers << endl;
cout << "错误: " << wrongAnswers << endl;
cout << "得分: " << score << "%" << endl;
}
};
// 生成随机整数
int randomInt(int min, int max) {
return rand() % (max - min + 1) + min;
}
// 计算表达式结果
int calculateExpression(const string& expr) {
stack<int> nums;
stack<char> ops;
int num = 0;
for (size_t i = 0; i < expr.size(); ++i) {
char c = expr[i];
if (isdigit(c)) {
num = num * 10 + (c - '0');
}
else if (c == '+' || c == '-' || c == '*' || c == '/') {
nums.push(num);
num = 0;
// 处理高优先级运算符
if (!ops.empty() && (ops.top() == '*' || ops.top() == '/')) {
char op = ops.top(); ops.pop();
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
if (op == '*') nums.push(a * b);
else nums.push(a / b);
}
ops.push(c);
}
}
nums.push(num);
// 处理剩余运算
while (!ops.empty()) {
char op = ops.top(); ops.pop();
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
if (op == '+') nums.push(a + b);
else if (op == '-') nums.push(a - b);
else if (op == '*') nums.push(a * b);
else nums.push(a / b);
}
return nums.top();
}
// 检查表达式是否有效
bool isValidExpression(const string& expr) {
try {
int result = calculateExpression(expr);
return result >= 0 && result <= 1000;
} catch (...) {
return false;
}
}
// 生成一个有效的表达式
string generateUniqueExpression(set<string>& existingExpressions) {
vector<char> operators = {'+', '-', '*', '/'};
string expr;
int attempts = 0;
const int maxAttempts = 1000;
while (attempts < maxAttempts) {
char op1 = operators[randomInt(0, 3)];
char op2 = operators[randomInt(0, 3)];
int num1 = randomInt(1, 100);
int num2 = randomInt(1, 100);
int num3 = randomInt(1, 100);
// 确保除法能整除
if (op1 == '/') {
vector<int> factors;
for (int i = 1; i <= num1; ++i) {
if (num1 % i == 0) factors.push_back(i);
}
if (!factors.empty()) {
num2 = factors[randomInt(0, factors.size() - 1)];
}
}
if (op2 == '/') {
int temp;
if (op1 == '+') temp = num1 + num2;
else if (op1 == '-') temp = num1 - num2;
else if (op1 == '*') temp = num1 * num2;
else temp = num1 / num2;
if (temp > 0) {
vector<int> factors;
for (int i = 1; i <= temp; ++i) {
if (temp % i == 0) factors.push_back(i);
}
if (!factors.empty()) {
num3 = factors[randomInt(0, factors.size() - 1)];
}
}
}
int bracketType = randomInt(0, 2);
char buffer[100];
switch (bracketType) {
case 0:
snprintf(buffer, sizeof(buffer), "%d %c %d %c %d", num1, op1, num2, op2, num3);
break;
case 1:
snprintf(buffer, sizeof(buffer), "(%d %c %d) %c %d", num1, op1, num2, op2, num3);
break;
case 2:
snprintf(buffer, sizeof(buffer), "%d %c (%d %c %d)", num1, op1, num2, op2, num3);
break;
}
expr = buffer;
if (isValidExpression(expr) && existingExpressions.find(expr) == existingExpressions.end()) {
existingExpressions.insert(expr);
return expr;
}
attempts++;
}
// 如果多次尝试失败,生成一个简单且唯一的表达式
string uniqueExpr;
do {
int a = randomInt(1, 50);
int b = randomInt(1, 50);
while (a % b != 0) b = randomInt(1, a);
char buffer[50];
snprintf(buffer, sizeof(buffer), "%d / %d + %d", a, b, randomInt(0, 10));
uniqueExpr = buffer;
} while (existingExpressions.find(uniqueExpr) != existingExpressions.end());
existingExpressions.insert(uniqueExpr);
return uniqueExpr;
}
int main() {
srand(time(0));
const int totalProblems = 300;
const int problemsPerLine = 5;
set<string> existingExpressions;
ScoreSystem scoreSystem;
cout << "生成 " << totalProblems << " 道四则运算练习题:" << endl;
cout << "----------------------------------------" << endl;
cout << "要求:1. 100以内数字 2. 两个运算符 3. 除法结果必须为整数 4. 所有题目不同" << endl;
cout << "----------------------------------------" << endl;
// 生成题目
vector<pair<string, int>> problems;
for (int i = 0; i < totalProblems; ++i) {
string problem = generateUniqueExpression(existingExpressions);
int answer = calculateExpression(problem);
problems.emplace_back(problem, answer);
}
// 显示题目并获取用户答案
for (int i = 0; i < totalProblems; ++i) {
cout << (i + 1) << ". " << problems[i].first << " = ";
int userAnswer;
cin >> userAnswer;
if (userAnswer == problems[i].second) {
cout << "正确!\n";
scoreSystem.addCorrect();
} else {
cout << "错误!正确答案是: " << problems[i].second << "\n";
scoreSystem.addWrong();
}
// 每5题显示一次当前统计
if ((i + 1) % problemsPerLine == 0) {
scoreSystem.displayStats();
cout << "----------------------------------------" << endl;
}
}
// 最终统计
cout << "\n====== 最终成绩 ======" << endl;
scoreSystem.displayStats();
cout << "=====================" << endl;
// 根据得分给出评价
if (scoreSystem.score >= 90) {
cout << "优秀!继续保持!" << endl;
} else if (scoreSystem.score >= 70) {
cout << "良好!还有提升空间!" << endl;
} else if (scoreSystem.score >= 60) {
cout << "及格!需要多加练习!" << endl;
} else {
cout << "不及格!建议重新学习基础知识!" << endl;
}
return 0;
}
设计思路:首先确定规则 1.100以内数字 2.两个运算符 3.除法结果必须为整数 4.所有题目不同 5.设计一个简单的得分系统
首先完成四则运算的基本规则的完成
点击查看代码
// 生成随机整数
int randomInt(int min, int max) {
return rand() % (max - min + 1) + min;
}
// 检查表达式是否有效
bool isValidExpression(const string& expr) {
stack<int> nums;
stack<char> ops;
int num = 0;
for (size_t i = 0; i < expr.size(); ++i) {
char c = expr[i];
if (isdigit(c)) {
num = num * 10 + (c - '0');
}
else if (c == '+' || c == '-' || c == '*' || c == '/') {
nums.push(num);
num = 0;
// 处理高优先级运算符
if (!ops.empty() && (ops.top() == '*' || ops.top() == '/')) {
char op = ops.top(); ops.pop();
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
if (op == '*') nums.push(a * b);
else {
if (b == 0) return false;
if (a % b != 0) return false;
nums.push(a / b);
}
}
ops.push(c);
}
}
nums.push(num);
// 处理剩余运算
while (!ops.empty()) {
char op = ops.top(); ops.pop();
int b = nums.top(); nums.pop();
int a = nums.top(); nums.pop();
if (op == '+') nums.push(a + b);
else if (op == '-') nums.push(a - b);
else if (op == '*') nums.push(a * b);
else {
if (b == 0) return false;
if (a % b != 0) return false;
nums.push(a / b);
}
}
int result = nums.top();
return result >= 0 && result <= 1000;
}
点击查看代码
// 生成一个有效的表达式
string generateUniqueExpression(set<string>& existingExpressions) {
vector<char> operators;
operators.push_back('+');
operators.push_back('-');
operators.push_back('*');
operators.push_back('/');
string expr;
int attempts = 0;
const int maxAttempts = 1000; // 增加尝试次数以确保唯一性
while (attempts < maxAttempts) {
char op1 = operators[randomInt(0, 3)];
char op2 = operators[randomInt(0, 3)];
int num1 = randomInt(1, 100);
int num2 = randomInt(1, 100);
int num3 = randomInt(1, 100);
点击查看代码
// 确保除法能整除
if (op1 == '/') {
vector<int> factors;
for (int i = 1; i <= num1; ++i) {
if (num1 % i == 0) factors.push_back(i);
}
if (!factors.empty()) {
num2 = factors[randomInt(0, factors.size() - 1)];
}
}
if (op2 == '/') {
int temp;
if (op1 == '+') temp = num1 + num2;
else if (op1 == '-') temp = num1 - num2;
else if (op1 == '*') temp = num1 * num2;
else temp = num1 / num2;
if (temp > 0) {
vector<int> factors;
for (int i = 1; i <= temp; ++i) {
if (temp % i == 0) factors.push_back(i);
}
if (!factors.empty()) {
num3 = factors[randomInt(0, factors.size() - 1)];
}
}
}
int bracketType = randomInt(0, 2);
char buffer[100];
switch (bracketType) {
case 0:
snprintf(buffer, sizeof(buffer), "%d %c %d %c %d", num1, op1, num2, op2, num3);
break;
case 1:
snprintf(buffer, sizeof(buffer), "(%d %c %d) %c %d", num1, op1, num2, op2, num3);
break;
case 2:
snprintf(buffer, sizeof(buffer), "%d %c (%d %c %d)", num1, op1, num2, op2, num3);
break;
}
expr = buffer;
if (isValidExpression(expr) && existingExpressions.find(expr) == existingExpressions.end()) {
existingExpressions.insert(expr);
return expr;
}
attempts++;
}
// 如果多次尝试失败,生成一个简单且唯一的表达式
string uniqueExpr;
do {
int a = randomInt(1, 50);
int b = randomInt(1, 50);
while (a % b != 0) b = randomInt(1, a);
char buffer[50];
snprintf(buffer, sizeof(buffer), "%d / %d + %d", a, b, randomInt(0, 10));
uniqueExpr = buffer;
} while (existingExpressions.find(uniqueExpr) != existingExpressions.end());
existingExpressions.insert(uniqueExpr);
return uniqueExpr;
}
点击查看代码
// 得分系统结构体
struct ScoreSystem {
int totalProblems = 0;
int correctAnswers = 0;
int wrongAnswers = 0;
double score = 0.0;
void addCorrect() {
correctAnswers++;
totalProblems++;
calculateScore();
}
void addWrong() {
wrongAnswers++;
totalProblems++;
calculateScore();
}
void calculateScore() {
if (totalProblems > 0) {
score = round((double)correctAnswers / totalProblems * 100);
}
}
void displayStats() {
cout << "\n===== 答题统计 =====" << endl;
cout << "总题数: " << totalProblems << endl;
cout << "正确: " << correctAnswers << endl;
cout << "错误: " << wrongAnswers << endl;
cout << "得分: " << score << "%" << endl;
}
}
点击查看代码
// 生成题目
vector<pair<string, int>> problems;
for (int i = 0; i < totalProblems; ++i) {
string problem = generateUniqueExpression(existingExpressions);
int answer = calculateExpression(problem);
problems.emplace_back(problem, answer);
}
// 显示题目并获取用户答案
for (int i = 0; i < totalProblems; ++i) {
cout << (i + 1) << ". " << problems[i].first << " = ";
int userAnswer;
cin >> userAnswer;
if (userAnswer == problems[i].second) {
cout << "正确!\n";
scoreSystem.addCorrect();
} else {
cout << "错误!正确答案是: " << problems[i].second << "\n";
scoreSystem.addWrong();
}
// 每5题显示一次当前统计
if ((i + 1) % problemsPerLine == 0) {
scoreSystem.displayStats();
cout << "----------------------------------------" << endl;
}
}
// 最终统计
cout << "\n====== 最终成绩 ======" << endl;
scoreSystem.displayStats();
cout << "=====================" << endl;
// 根据得分给出评价
if (scoreSystem.score >= 90) {
cout << "优秀!继续保持!" << endl;
} else if (scoreSystem.score >= 70) {
cout << "良好!还有提升空间!" << endl;
} else if (scoreSystem.score >= 60) {
cout << "及格!需要多加练习!" << endl;
} else {
cout << "不及格!建议重新学习基础知识!" << endl;
}
return 0;
}
分工协作,高效互补:我主要负责表达式生成算法和唯一性校验,而同学负责得分系统和用户交互。在编写代码时,我们一人编写代码,另一人实时审查,发现并修正了多个潜在错误,比如除零异常和括号匹配问题。
思维碰撞,优化设计:在讨论如何保证题目不重复时,我们尝试了多种方案,最终采用标准化表达式的方法,既保证了效率,又避免了重复。此外,同学提出的每5题反馈进度的设计,让体验大幅提升。
沟通与调试的挑战:由于编程风格不同,初期在代码合并时出现了冲突,但通过Git版本管理和详细注释,我们很快适应了彼此的节奏。
这次合作让我认识到,结对编程不仅能减少错误,还能激发更好的解决方案。未来我们会继续努力,进一步提升代码质量。

浙公网安备 33010602011771号