软件开发结对编程
结对编程同伴:2352509
采用C++语言编程
一、算法设计思路
- 基础版本设计
核心算法:
随机数生成:使用rand() % 100 + 1生成1-100的随机数
运算符随机选择:通过rand() % 4随机选择加减乘除
运算优先级处理:通过条件判断(op1 >= 2 && op2 < 2)识别需要优先计算的运算符组合
结果验证:确保运算结果在0-1000范围内,否则重新生成
数据结构:
使用Question结构体存储题目表达式、正确答案、用户答案和判断结果
使用vector
关键函数:
generateTwoOperatorExpression:生成双运算符题目
showResults:显示练习结果
intToString:替代不兼容的to_string函数
- 难度扩展版本设计
难度分级机制:
enum Difficulty {
EASY, // 简单:单运算符,小数字(1-20)
MEDIUM, // 中等:双运算符,中等数字(10-50)
HARD, // 较难:双运算符,大数字(30-100)
EXTREME // 困难:双运算符,更多除法(50-100)
};
难度控制实现:
-
数字范围控制:
void getNumberRange(Difficulty diff, int& minNum, int& maxNum) {
switch(diff) {
case EASY: minNum=1; maxNum=20; break;
case MEDIUM: minNum=10; maxNum=50; break;
// ...
}
} -
运算符控制:
void getOperators(Difficulty diff, int& op1, int& op2) {
switch(diff) {
case EASY: op1=rand()%2; op2=-1; break; // 只有加减
case EXTREME: // 增加除法概率
if(rand()%2) op1=3;
if(rand()%2) op2=3;
break;
}
} -
智能重试机制:
if(finalResult<0 || finalResult>1000 || isnan(finalResult)) {
generateExpression(questionNum, diff); // 重新生成
return;
}
结果统计增强:
按难度级别分别统计正确率
总正确率计算
详细的题目回顾功能
二、程序代码
第一版(没有难易程度):
点击查看代码
include <iostream>
include <cstdlib>
include <ctime>
include <string>
include <vector>
include <cmath>
include <sstream> // 用于替代to_string
using namespace std;
// 存储题目和答案的结构体
struct Question {
string expression;
double correctAnswer;
double userAnswer;
bool isCorrect;
};
vector<Question> questions; // 存储所有问题
// 整数转字符串函数(替代to_string)
string intToString(int num) {
stringstream ss;
ss << num;
return ss.str();
}
// 生成包含两个运算符的算术表达式
void generateTwoOperatorExpression(int questionNum) {
// 生成三个100以内的随机数
int num1 = rand() % 100 + 1; // 1-100
int num2 = rand() % 100 + 1;
int num3 = rand() % 100 + 1;
// 随机选择两个运算符 (0:+, 1:-, 2:, 3:/)
int op1 = rand() % 4;
int op2 = rand() % 4;
char operations[2];
double intermediateResult, finalResult;
string expression;
// 第一个运算符
operations[0] = (op1 == 0) ? '+' :
(op1 == 1) ? '-' :
(op1 == 2) ? '' : '/';
// 第二个运算符
operations[1] = (op2 == 0) ? '+' :
(op2 == 1) ? '-' :
(op2 == 2) ? '' : '/';
// 计算表达式结果(考虑运算优先级)
if ((op1 >= 2 && op2 < 2) || (op1 < 2 && op2 < 2)) {
// 先计算第一个运算
switch(op1) {
case 0: intermediateResult = num1 + num2; break;
case 1: intermediateResult = num1 - num2; break;
case 2: intermediateResult = num1 num2; break;
case 3: intermediateResult = static_cast<double>(num1) / num2; break;
}
// 然后计算第二个运算
switch(op2) {
case 0: finalResult = intermediateResult + num3; break;
case 1: finalResult = intermediateResult - num3; break;
case 2: finalResult = intermediateResult num3; break;
case 3: finalResult = intermediateResult / num3; break;
}
expression = intToString(num1) + " " + operations[0] + " " +
intToString(num2) + " " + operations[1] + " " +
intToString(num3) + " = ";
} else {
// 先计算第二个运算
switch(op2) {
case 0: intermediateResult = num2 + num3; break;
case 1: intermediateResult = num2 - num3; break;
case 2: intermediateResult = num2 num3; break;
case 3: intermediateResult = static_cast<double>(num2) / num3; break;
}
// 然后计算第一个运算
switch(op1) {
case 0: finalResult = num1 + intermediateResult; break;
case 1: finalResult = num1 - intermediateResult; break;
case 2: finalResult = num1 intermediateResult; break;
case 3: finalResult = num1 / intermediateResult; break;
}
expression = intToString(num1) + " " + operations[0] + " (" +
intToString(num2) + " " + operations[1] + " " +
intToString(num3) + ") = ";
}
// 确保结果在0-1000之间
if (finalResult < 0 || finalResult > 1000 || isnan(finalResult)) {
generateTwoOperatorExpression(questionNum); // 重新生成
return;
}
// 显示题目
cout << "问题 " << questionNum << ": " << expression;
// 获取用户答案
double userAnswer;
cin >> userAnswer;
// 存储问题信息
Question q;
q.expression = expression;
q.correctAnswer = finalResult;
q.userAnswer = userAnswer;
q.isCorrect = fabs(userAnswer - finalResult) < 0.001;
questions.push_back(q);
}
// 显示练习结果
void showResults() {
cout << "\n======== 练习结果 ========\n";
int correctCount = 0;
for (size_t i = 0; i < questions.size(); ++i) {
cout << "问题 " << i+1 << ": " << questions[i].expression << endl;
cout << "你的答案: " << questions[i].userAnswer << endl;
cout << "正确答案: " << questions[i].correctAnswer << endl;
if (questions[i].isCorrect) {
cout << "结果: 正确!\n";
correctCount++;
} else {
cout << "结果: 错误!\n";
}
cout << "------------------------\n";
}
cout << "总结: 你答对了 " << correctCount << " 题,共 " << questions.size() << " 题\n";
cout << "正确率: " << (correctCount 100 / questions.size()) << "%\n";
}
int main() {
srand(time(0)); // 初始化随机数种子
cout << "双运算符四则运算练习 (数字范围1-100)\n";
cout << "输入你的答案后按回车\n";
cout << "所有题目完成后会显示结果\n";
cout << "==============================\n";
int questionCount = 10; // 设置题目数量
// 生成题目
for (int i = 0; i < questionCount; ++i) {
generateTwoOperatorExpression(i+1);
}
// 显示结果
showResults();
system("pause"); // Dev-C++专用,防止窗口一闪而过
return 0;
}
第二版(加入难易程度):
点击查看代码
include <iostream>
include <cstdlib>
include <ctime>
include <string>
include <vector>
include <cmath>
include <sstream>
using namespace std;
// 难度级别枚举
enum Difficulty {
EASY, // 简单:最多一个运算符,数字小
MEDIUM, // 中等:两个运算符,数字中等
HARD, // 较难:两个运算符,数字较大
EXTREME // 困难:两个运算符,包含更多除法
};
// 前向声明函数
string getDifficultyName(Difficulty diff);
// 存储题目和答案的结构体
struct Question {
string expression;
double correctAnswer;
double userAnswer;
bool isCorrect;
Difficulty difficulty;
};
vector<Question> questions;
// 整数转字符串函数
string intToString(int num) {
stringstream ss;
ss << num;
return ss.str();
}
// 获取难度名称
string getDifficultyName(Difficulty diff) {
switch(diff) {
case EASY: return "简单";
case MEDIUM: return "中等";
case HARD: return "较难";
case EXTREME: return "困难";
default: return "未知";
}
}
// 根据难度获取数字范围
void getNumberRange(Difficulty diff, int& minNum, int& maxNum) {
switch(diff) {
case EASY: minNum = 1; maxNum = 20; break;
case MEDIUM: minNum = 10; maxNum = 50; break;
case HARD: minNum = 30; maxNum = 100; break;
case EXTREME: minNum = 50; maxNum = 100; break;
}
}
// 根据难度生成运算符
void getOperators(Difficulty diff, int& op1, int& op2) {
switch(diff) {
case EASY: // 简单:只用一个运算符
op1 = rand() % 2; // 只有加减
op2 = -1; // 表示没有第二个运算符
break;
case MEDIUM: // 中等:两个运算符,主要是加减
op1 = rand() % 2;
op2 = rand() % 3; // 加减乘
break;
case HARD: // 较难:两个运算符,包含乘除
op1 = rand() % 3;
op2 = rand() % 4;
break;
case EXTREME: // 困难:两个运算符,更多除法
op1 = rand() % 4;
op2 = rand() % 4;
if (rand() % 2) op1 = 3; // 增加除法概率
if (rand() % 2) op2 = 3;
break;
}
}
// 生成算术表达式
void generateExpression(int questionNum, Difficulty diff) {
int minNum, maxNum;
getNumberRange(diff, minNum, maxNum);
int num1 = rand() % (maxNum - minNum + 1) + minNum;
int num2 = rand() % (maxNum - minNum + 1) + minNum;
int num3 = (diff == EASY) ? 0 : rand() % (maxNum - minNum + 1) + minNum;
int op1, op2;
getOperators(diff, op1, op2);
char operations[2];
double intermediateResult, finalResult;
string expression;
operations[0] = (op1 == 0) ? '+' :
(op1 == 1) ? '-' :
(op1 == 2) ? '' : '/';
// 简单难度只有一个运算符
if (diff == EASY) {
switch(op1) {
case 0: finalResult = num1 + num2; break;
case 1: finalResult = num1 - num2; break;
}
expression = intToString(num1) + " " + operations[0] + " " +
intToString(num2) + " = ";
}
else { // 其他难度有两个运算符
operations[1] = (op2 == 0) ? '+' :
(op2 == 1) ? '-' :
(op2 == 2) ? '' : '/';
// 考虑运算优先级
if ((op1 >= 2 && op2 < 2) || (op1 < 2 && op2 < 2)) {
// 先算第一个运算
switch(op1) {
case 0: intermediateResult = num1 + num2; break;
case 1: intermediateResult = num1 - num2; break;
case 2: intermediateResult = num1 num2; break;
case 3: intermediateResult = static_cast<double>(num1) / num2; break;
}
// 再算第二个运算
switch(op2) {
case 0: finalResult = intermediateResult + num3; break;
case 1: finalResult = intermediateResult - num3; break;
case 2: finalResult = intermediateResult num3; break;
case 3: finalResult = intermediateResult / num3; break;
}
expression = intToString(num1) + " " + operations[0] + " " +
intToString(num2) + " " + operations[1] + " " +
intToString(num3) + " = ";
} else {
// 先算第二个运算
switch(op2) {
case 0: intermediateResult = num2 + num3; break;
case 1: intermediateResult = num2 - num3; break;
case 2: intermediateResult = num2 num3; break;
case 3: intermediateResult = static_cast<double>(num2) / num3; break;
}
// 再算第一个运算
switch(op1) {
case 0: finalResult = num1 + intermediateResult; break;
case 1: finalResult = num1 - intermediateResult; break;
case 2: finalResult = num1 intermediateResult; break;
case 3: finalResult = num1 / intermediateResult; break;
}
expression = intToString(num1) + " " + operations[0] + " (" +
intToString(num2) + " " + operations[1] + " " +
intToString(num3) + ") = ";
}
}
// 确保结果在0-1000之间
if (finalResult < 0 || finalResult > 1000 || isnan(finalResult)) {
generateExpression(questionNum, diff); // 重新生成
return;
}
// 显示题目
cout << "问题 " << questionNum << " (" << getDifficultyName(diff) << "): " << expression;
// 获取用户答案
double userAnswer;
cin >> userAnswer;
// 存储问题信息
Question q;
q.expression = expression;
q.correctAnswer = finalResult;
q.userAnswer = userAnswer;
q.isCorrect = fabs(userAnswer - finalResult) < 0.001;
q.difficulty = diff;
questions.push_back(q);
}
// 显示练习结果
void showResults() {
cout << "\n======== 练习结果 ========\n";
int correctCount = 0;
int diffCorrect[4] = {0}; // 各难度正确计数
int diffTotal[4] = {0}; // 各难度总题数
for (size_t i = 0; i < questions.size(); ++i) {
Difficulty diff = questions[i].difficulty;
diffTotal[diff]++;
cout << "问题 " << i+1 << " (" << getDifficultyName(diff) << "): "
<< questions[i].expression << endl;
cout << "你的答案: " << questions[i].userAnswer << endl;
cout << "正确答案: " << questions[i].correctAnswer << endl;
if (questions[i].isCorrect) {
cout << "结果: 正确!\n";
correctCount++;
diffCorrect[diff]++;
} else {
cout << "结果: 错误!\n";
}
cout << "------------------------\n";
}
cout << "\n======= 总结 =======\n";
cout << "总正确率: " << correctCount << "/" << questions.size() << " ("
<< (questions.size() ? (correctCount 100 / questions.size()) : 0) << "%)\n";
// 各难度正确率
for (int i = 0; i < 4; i++) {
if (diffTotal[i] > 0) {
cout << getDifficultyName(static_cast<Difficulty>(i)) << "难度: "
<< diffCorrect[i] << "/" << diffTotal[i] << " ("
<< (diffCorrect[i] 100 / diffTotal[i]) << "%)\n";
}
}
}
// 选择难度
Difficulty selectDifficulty() {
cout << "请选择难度级别:\n";
cout << "1. 简单\n";
cout << "2. 中等\n";
cout << "3. 较难\n";
cout << "4. 困难\n";
cout << "输入选项(1-4): ";
int choice;
cin >> choice;
while (choice < 1 || choice > 4) {
cout << "无效输入,请重新选择(1-4): ";
cin >> choice;
}
return static_cast<Difficulty>(choice - 1);
}
int main() {
srand(time(0));
cout << "四则运算练习 (结果范围0-1000)\n";
cout << "==============================\n";
Difficulty diff = selectDifficulty();
int questionCount = 10;// 设置题目数量
// 生成题目
for (int i = 0; i < questionCount; ++i) {
generateExpression(i+1, diff);
}
// 显示结果
showResults();
system("pause");
return 0;
}
三、运算结果
第一版(没有难易程度):


第二版(加入难易程度):






四、结对编程作业体会
2329311:
此次合作让我深刻体会到结对编程的优势:一是效率提升,双人审核显著减少代码错误;二是知识互补,搭档对随机数生成的建议简化了校验流程;三是强化沟通能力,尤其在需求细节对齐时需清晰表达。改进方向包括扩展题目难度或增加图形界面。最终,我们成功完成了四则运算练习程序。这次实践不仅巩固了编程技能,更让我认识到协作开发的价值。
2352509:
通过这次结对编程实践,我们不仅完成了一个功能完善的四则运算练习程序,还深刻体会到了协作开发的价值。从最初的基础版本到支持多难度级别的最终版本,整个过程充满了技术挑战和学习机会。我们学会了如何更好地分工合作、解决兼容性问题、设计友好的用户界面,这些经验将对未来的编程项目产生持久影响。

浙公网安备 33010602011771号