结对编程-运算练习题小程序

小学老师要每周给同学出300道四则运算练习题。
两个运算符,100 以内的数字,不需要写答案。
需要检查答案是否正确,并且保证答案在 0..1000 之间
尽可能地多设置一些条件

算法设计思路

运算符与优先级处理

定义运算符优先级:+/-为1级,*//为2级。
左结合但优先级优先:若第二个运算符优先级更高(如+后接),先计算第二个运算(如a + b * c会先算b * c)。
计算函数calculate通过判断优先级决定运算顺序,确保结果符合数学规则。

合法表达式生成

数值范围:随机生成0-100的整数。
减法合法性:若运算符为-,确保被减数≥减数(如a ≥ b)。
除法合法性:若运算符为/,确保除数≠0且能整除(如a % b == 0)。
分步验证:首先生成前两步运算的中间结果,再检查第二步运算的合法性(如中间结果是否≥c)。

结果范围控制

最终结果必须满足0 ≤ res ≤ 1000,否则重新生成表达式。

用户交互与评分

每组10题,累计得分,输入答案后实时反馈正确性。
输入缓冲区清空处理(while (getchar() != '\n')),避免回车符干扰。

点击查看代码
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 生成运算符对应的字符
int get_priority(int op) { return (op <= 1) ? 1 : 2; }
char get_operator(int op) {
    switch(op) {case 0:return '+'; case 1:return '-'; case 2:return '*'; case 3:return '/'; default:return '+';}
}
// 计算三数表达式结果(左结合,不考虑优先级)
int calculate(int a, int op1, int b, int op2, int c) {
    int mid, res;
    // 判断优先级:如果第二个运算符优先级更高(如+ *),先算后面的乘除
    if (get_priority(op2) > get_priority(op1)) {
        // 先计算 b op2 c
        switch(op2) {case 2:mid = b * c; break; case 3:mid = b / c; break; case 0:mid = b + c; break; case 1:mid = b - c;}
        // 再计算 a op1 mid
        switch(op1) {case 0:res = a + mid; break; case 1:res = a - mid; break; case 2:res = a * mid; break; case 3:res = a / mid;}
    } else {
        // 先计算 a op1 b
        switch(op1) {case 2:mid = a * b; break; case 3:mid = a / b; break; case 0:mid = a + b; break; case 1:mid = a - b;}
        // 再计算 mid op2 c
        switch(op2) {case 0:res = mid + c; break; case 1:res = mid - c; break; case 2:res = mid * c; break; case 3:res = mid / c;}
    }
    return res;
}
int main() {
    int answer, score;
    srand(time(NULL));
    
    for (int k = 0; k < 30; k++) {
        score = 0;
        for (int i = 0; i < 10; i++) {
            int a, b, c, op1, op2, res;
            
            // 生成合法的三数表达式(两步运算均无负数、小数,结果≤1000)
            while (1) {
                a = rand() % 101;
                b = rand() % 101;
                c = rand() % 101;
                op1 = rand() % 4;  // 第一个运算符
                op2 = rand() % 4;  // 第二个运算符
                
                // 第一步运算合法性检查(减法/除法)
                if (op1 == 1 && a < b) continue;       // 减法:被减数≥减数
                if (op1 == 3 && (b == 0 || a % b != 0)) continue;  // 除法:除数≠0且整除
                
                int res1 = calculate(a, op1, b, 0, 0);  // 仅计算第一步结果(忽略op2参数)
                
                // 第二步运算合法性检查(减法/除法+结果≤1000)
                if (op2 == 1 && res1 < c) continue;       // 减法:前结果≥第三数
                if (op2 == 3 && (c == 0 || res1 % c != 0)) continue;  // 除法:除数≠0且整除
                res = calculate(a, op1, b, op2, c);       // 完整计算
                if (res > 1000) continue; 
if (res < 0) continue;                
                
                break;  // 所有条件满足,退出循环
            }
            
            // 输出题目(三数两运算符,左结合)
            printf("%3d %c %3d %c %3d = ?\n", a, get_operator(op1), b, get_operator(op2), c);
            scanf("%d", &answer);
            
            // 答案验证
            if (answer == res) {
                printf("答案正确!\n");
                score += 10;
            } else {
                printf("答案错误,正确答案是:%d\n", res);
            }
        }
        printf("这10题的得分是! %d\n", score);
        if(score > 60){printf("你获得了 MVP!\n");}
else{printf("你是 town in go!\n");} 
        printf("输入任意字符继续:");
        while (getchar() != '\n');  // 清空输入缓冲区
        getchar();  // 等待用户输入
    }
    
    return 0;
}

运算结果

image
image

结对编程作业体会

关键挑战与解决方案

运算顺序处理:最初未考虑优先级,导致a + b * c类题目结果错误。通过引入优先级判断和分步计算解决。
除法边界条件:发现未处理b=0或res1=0的情况,增加条件c != 0 && res1 % c == 0。
效率优化:生成合法表达式时可能多次重试,通过约束随机数范围(如首先生成a ≥ b)减少无效循环。

协作经验

分工明确:一人负责表达式生成与合法性检查,另一人专注计算逻辑和用户交互。
测试驱动:通过编写测试用例(如5 - 3 * 2应得-1而非4)验证计算逻辑正确性。

改进方向

题目多样性:支持括号或更多运算符组合,增加难度层次。
错误统计:记录学生常错题型,生成针对性练习。
界面优化:支持图形化界面或导出题目到文件,便于教师使用。

小组成员:2352814 袁璟博;2352837 刘星玮

posted @ 2025-04-14 12:35  江寒懿  阅读(42)  评论(0)    收藏  举报