结对编程——小学数学四则运算题目生成系统
导语
"当两位大学生试图用C++解救被四则运算题海淹没的小学老师时,代码最初长得像被猫踩过的键盘。直到他们开启结对编程模式——一个写代码,一个当人肉编译器,这场灾难才变成教科书级的协作教学案例..."
(另一位战友的学号是2350218)
一、项目背景与需求分析
经过两个人紧张又严密的讨论:
小学教师每周需要手动制作300道满足以下特定要求的四则运算练习题:
1.运算规则:包含两个运算符的混合运算(如12+34-56)
2.数值范围:运算数在1-100之间
3.结果约束:最终答案必须∈[0,1000]
4.功能要求:实时验证答案正确性,统计正确率
二.代码思路的构建
项目全程涉及两个代码(源1.cpp和源2.cpp),这是由原稿到终稿的转变。
初代驾驶员设计思路:
源1.cpp 尝试实现一个交互式四则运算练习系统,主要功能包括:
1.随机生成单运算符算式(如 x + y)
2.用户输入答案并判断正误
3.统计正确率
4.限制题目数量(300道)
核心代码逻辑
(1) 算式生成
点击查看代码
x = rand()%(100-1+1)+1; // 生成1~100的随机数
y = rand() % (100 - 1 + 1) + 1;
char op = a[c_change]; // 从{+,-,*,/}中随机选运算符
cout << x << op << y << "=" << endl;
缺点:
-
使用rand()生成随机数,但未播种(导致每次运行生成相同序列)
-
运算符选择逻辑不完整(c_change未随机化)
-
仅支持单运算符,与需求不符
(2) 答案验证
点击查看代码
void judge(int ans) {
int b;
if (a[c_change] = '+') b = x + y; // 错误:误用赋值运算符=
if (a[c_change] = '-') b = x - y; // 应使用==
// ...其他运算符...
b == o; // 无实际作用的语句
}
缺点:
-
条件判断失效:全部用赋值运算符而非比较
-
结果未利用:计算出的b未与用户答案ans比较
-
整数除法:未处理/运算的整除约束
(3) 用户交互
点击查看代码
void ui() {
printf("(生成一道题:1,查询现正确率:2)");
if (choice) { // 逻辑错误:非0即执行
printf(" 习题%d:", num++);
cin >> ans; // 未调用judge()验证答案
}
else if (choice != 1 || choice != 2) { // 永远为真
cout << "请重新输入:\n";
}
}
缺点:
-
分支逻辑混乱:条件判断存在逻辑错误
-
状态管理缺失:未统计正确/错误次数
-
功能未闭环:生成题目与验证答案未关联
结对诊断:
"驾驶员"信誓旦旦说能运行,"领航员"盯着屏幕瞳孔地震。两人发现:
-
UI逻辑黑洞:选择菜单像走迷宫(输入2会触发生成题目)
-
随机数裸奔:没播种导致每次生成相同题目
-
正确率玄学:t变量未初始化就直接除
源1.cpp展现诸多典型问题:
-
对需求理解不完整
-
基础语法掌握不牢
-
缺乏模块化设计意识
-
但这个基本框架(随机数生成、交互循环)为后续优化提供了基础。通过结对编程中的实时代码审查,这类问题可在开发早期被发现和修正。
附上源1cpp:
点击查看代码
#include<iostream>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
using namespace std;
char a[4] = { '+','-','*','/'};
int c_change = 1;
double x, y;// 100以内
char poit;
int res;//0--1000
int exit = 1;
int num=1;
int choice;
int ans;
int f, o;
double t;
void output_equation()
{
x = rand()%(100-1+1)+1;//1到100的数范围
y = rand() % (100 - 1 + 1) + 1;
if (is_equation) cout << x << c_change << y <<"=" << endl;
}
void judge(int ans)
{
int b;
if (a[c_change] = '+') b = x + y;
if (a[c_change] = '-') b = x - y;
if (a[c_change] = '*') b = x * y;
if (a[c_change] = '/') b = x / y;
b == o;//判断正确逻辑缺漏
}
void ui()
{
printf(" 练习系统 \n");
printf(" 请选择操作: ");
cin >> choice;
printf("(生成一道题:1,查询现正确率:2)");
cout << "\n";
if (choice)
{
printf(" 习题%d:", num++);
printf(" 请输入答案:");
cin >> ans;//true结果计数缺漏
}
else if (choice != 1 || choice != 2)
{
cout << "请重新输入:\n";
ui();
}
else printf("正确率为:%.2lf\n", (double)t / num);////////////
}
int is_equation()
{
//int f, o;
if (a[c_change] = '+') o=x+y;
if (o >= 0 || o <= 1000) return 1;
else return 0;
}
int main()
{
while (1)
{
ui();
exit = exit + 1;
if (exit == 300)
{
cout << "所有题目已完成" << endl;
break;
}
cout << "\n";
}
return 0;
}
“领航员一把抢过键盘,决定开始对源1.cpp在原有的架构基础上进行修补,这背后道路的艰辛与否尚未可知······”
下面是源2.cpp的思路分析
核心代码逻辑:
(1) 表达式生成流程
点击查看代码
do {
// 1. 生成第一个运算符和操作数
x = rand() % 100 + 1;
sym1 = symbols[rand() % 4];
// 2. 处理除法特殊情况
if (sym1 == '/') {
y = get_random_factor(x); // 确保y是x的因数
} else {
y = rand() % 100 + 1;
}
// 3. 计算中间结果
int first_step = apply_op(x, y, sym1);
// 4. 生成第二个运算符和操作数
sym2 = symbols[rand() % 4];
if (sym2 == '/') {
z = get_random_factor(first_step);
} else {
z = rand() % 100 + 1;
}
// 5. 验证最终结果
correct_result = apply_op(first_step, z, sym2);
} while (correct_result < 0 || correct_result > 1000);
优化点:
-
使用do-while确保结果合规
-
通过get_random_factor()保证整除
-
分步计算处理运算符优先级
(2) 安全除法实现
点击查看代码
vector<int> get_factors(int num) {
vector<int> factors;
for (int i = 1; i <= abs(num); ++i) {
if (num % i == 0) factors.push_back(i);
}
return factors;
}
特点:
-
预计算所有因数
-
处理负数情况(abs(num))
-
随机选择合法除数
“我们的运算练习系统有一个特色,它出的题目大部分都需要一点思维技巧才能轻松给出答案,是个锻炼思维,培养小聪明脑袋瓜的利器。”
另外其代码结构可作为教学范例,后续可扩展为:
-
支持分数运算
-
添加难度分级
-
增加错题重做功能
三.代码运行结果展示
1.初始界面
首页ui有三个功能选择:
- 生成题目
- 查看正确率
- 退出程序

2.生成题目

可以看到每次都可以选择生成下一个题目,另外也可以当前查看正确率。
3.完成题目

300题后自动退出
4.彩蛋

四.心得体会

两位开发者的血泪总结:
角色轮换:发现"驾驶员"沉迷写bug时,"领航员"要果断抢键盘
即时测试:每写5行代码就交替运行验证(避免堆积如山的问题)
代码相声:一个人写rand()%100时,另一个要喊停:"且慢!这里需要+1!"
老师课后点评:
"现在孩子们做题正确率提高了20%——因为程序终于不出错题了!下个月准备挑战分数运算?" (两位程序员闻言夺门而逃)

浙公网安备 33010602011771号