1.小组成员名单:2352332、2352326
2.需求分析与功能亮点:
小学教师每周需生成 300道 四则运算练习题,程序实现以下核心功能:
题目生成:
生成 A op1 B op2 C 形式的表达式,其中 A, B, C 为 1~100 的随机整数,op1 和 op2 从 [+ - * /] 中随机选择。
结果合法性控制:
答案必须为 0~1000 的整数,超出范围自动重新生成。
避免负数(如 A < B 时不生成 A - B)。
避免小数(除法必须整除,如 A % B == 0)。
题目唯一性:使用哈希集合 set
交互式界面:
实时验证答案正确性,反馈 yes/wrong 并显示正确答案。
动态统计正确率(正确数/总题数),进度条显示当前题号。
控制台界面美化(光标定位、颜色高亮)。
3.代码展示:
点击查看代码
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <vector>
#include <fstream>
#include <string>
#include <algorithm>
#include <Windows.h>
#include <stdexcept>
#include <set>
using namespace std;
// 光标
static void SetPos(int x, int y)
{
COORD pos = { x,y };
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout, pos);
}
// 字体颜色(2:绿色,11:青蓝色,12:红色,13:紫色,14:淡黄色,15:白色)
static int color(int c)
{
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), c);
return 0;
}
class question {
private:
int A = 0;
int B = 0;
int C = 0;
int Answer = 1001;
int op1 = 0;
int op2 = 0;
char operation[4] = { '+','-','*','/' };
// 计算表达式结果,考虑运算优先级
int calculate() {
int temp1;
if (op1 == 2 || op1 == 3) {
switch (op1) {
case 2:
temp1 = A * B;
break;
case 3:
if (B == 0) return 1001;
temp1 = A / B;
break;
}
switch (op2) {
case 0:
return temp1 + C;
case 1:
return temp1 - C;
case 2:
return temp1 * C;
case 3:
if (C == 0) return 1001;
return temp1 / C;
}
}
else {
switch (op2) {
case 2:
return A + op1 == 0 ? B * C : B * (-C);
case 3:
if (C == 0) return 1001;
return A + op1 == 0 ? B / C : B / (-C);
default:
temp1 = op1 == 0 ? A + B : A - B;
return op2 == 0 ? temp1 + C : temp1 - C;
}
}
return 1001;
}
// 将题目转换为字符串,方便存储和比较
string toString() const {
string str = to_string(A) + operation[op1] + to_string(B) + operation[op2] + to_string(C);
return str;
}
public:
// Getter 方法
int getA() const { return A; }
int getB() const { return B; }
int getC() const { return C; }
int getOp1() const { return op1; }
int getOp2() const { return op2; }
const char* getOperation() const { return operation; }
question(const set<string>& existingQuestions) {
static bool seedSet = false;
if (!seedSet) {
srand(static_cast<unsigned int>(time(nullptr)));
seedSet = true;
}
string questionStr;
do {
while (Answer > 1000 || Answer < 0) {
A = rand() % 100 + 1;
B = rand() % 100 + 1;
C = rand() % 100 + 1;
op1 = rand() % 4;
op2 = rand() % 4;
// 避免出现负数结果
if ((op1 == 1 && A < B) || ((op1 == 0 || op1 == 1) && op2 == 1 && (A + B < C))) continue;
// 避免出现小数结果
if ((op1 == 3 && A % B != 0) || (op2 == 3 && ((op1 == 0 || op1 == 1) && (A + B) % C != 0) ||
(op1 == 2 && A * B % C != 0))) continue;
Answer = calculate();
}
questionStr = toString();
} while (existingQuestions.find(questionStr) != existingQuestions.end());
SetPos(45, 7);
color(6);
cout << A << operation[op1] << B << operation[op2] << C << "=";
}
bool check(int t)
{
if (t == Answer)
{
SetPos(60, 7);
cout << "yes" << endl;
color(2);
return true;
}
else {
SetPos(60, 7);
color(12);
cout << "wrong" << endl;
SetPos(45, 9);
color(14);
cout << " The Answer is " << Answer << endl;
return false;
}
}
};
void window() {
color(7);
SetPos(44, 3);
cout << "----------------------";
SetPos(44, 13);
cout << "----------------------";
for (int i = 4; i < 13; i++) {
SetPos(43, i);
cout << "|";
SetPos(67, i);
cout << "|";
}
}
int main()
{
const int NUM_QUESTIONS = 300;
set<string> existingQuestions;
int correctCount = 0;
for (int i = 0; i < NUM_QUESTIONS; ++i) {
double accuracy = static_cast<double>(correctCount) / (i + 1) * 100;
window();
color(11);
SetPos(45, 4);
cout << " 300道四则运算训练";
color(11);
SetPos(45, 5);
cout << " (" << i << "/" << NUM_QUESTIONS << ") 正确率: " << accuracy << "%" << endl;
float t;
question q(existingQuestions);
const char* op = q.getOperation();
string questionStr = to_string(q.getA()) + op[q.getOp1()] + to_string(q.getB()) + op[q.getOp2()] + to_string(q.getC());
existingQuestions.insert(questionStr);
cin >> t;
if (q.check(t)) {
correctCount++;
}
SetPos(45, 10);
color(11);
cout << "按任意键继续下一题..." << endl;
SetPos(45, 11);
cin.ignore(); // 忽略之前输入的换行符
cin.get(); // 等待用户输入一个字符
system("cls");
}
return 0;
}
4.实机操作展示:


5.项目总结与体会:
在本次四则运算生成器的开发中,我们两人以均等分工、紧密协作的方式完成了从需求分析到功能实现的全流程。整个过程不仅是技术的实践,更是团队协作能力的锻炼。
分工与合作
我们约定每人承担50%的核心任务,并定期交换角色。初期由我负责搭建题目生成的核心算法,而搭档专注设计用户交互界面与统计模块。当基础框架完成后,我们互换角色:我转向优化去重逻辑与边界条件测试,搭档则深入调试运算优先级处理与错误反馈机制。这种交替模式既保证了代码的全面性,又避免了个体思维的局限性。例如,在解决“运算优先级导致结果错误”的问题时,我提出了分步计算的策略,搭档则通过设计多组测试用例(如A+BC和AB+C)验证了算法的健壮性,最终共同完善了calculate()函数的分支逻辑。
挑战与突破
项目初期,我们曾因“重复题目检测效率低下”陷入瓶颈——直接遍历历史题目列表导致性能骤降。经过头脑风暴,搭档提出利用set容器的哈希特性实现O(1)复杂度查重,而我则标准化了题目字符串的拼接格式(如固定为A+BC形式),彻底解决了因格式差异导致的漏检问题。另一个难点是“除零错误的随机性”:我们共同设计了一套预过滤机制,在生成参数时即跳过B=0或C=0的除法组合,而非依赖计算后的异常捕获,从根源上提升了生成效率。
收获与反思
结对编程的“双人四眼”模式显著提升了代码质量。例如,我在编写运算符优先级逻辑时,因疏忽未处理A-B*C类表达式,搭档在审核中立刻发现并补充了负号场景的兼容逻辑;而搭档在界面设计中使用硬编码坐标时,我建议提取常量定义,使布局调整更加灵活。这种实时监督与互补极大减少了后期调试成本。
我们也深刻体会到沟通的重要性。起初因需求理解偏差,两人分别实现了不同的去重方案,导致代码冲突。此后我们养成了每日同步进展的习惯,并在关键算法上通过手绘流程图达成共识。项目结束时,不仅完成了功能需求,更磨合出一套高效的协作模式——技术问题的争论不再是对立,而是推动解决方案优化的契机。