四则运算生成器

该项目是一个使用Java或C/C++编写的四则运算练习生成器,能够根据输入参数随机生成包含加减乘除的练习题,确保无负数和非整数结果。除了基本要求外,还支持括号运算和真分数的出题与运算。程序将生成的练习题及答案保存至'result.txt'文件。项目已更新至5.0版本,包括代码优化、功能增强等改进。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 任务描述

1.1 概述

使用java或C/C++编程语言,独立完成一个3到5个运算符的四则运算练习的软件

1.2 基本要求

  • 1 程序可接收一个输入参数n,然后随机产生n道加减乘除(分别使用符号±*÷来表示)练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间。

  • 2 每个练习题至少要包含2种运算符。同时,由于小学生没有分数与负数的概念,你所出的练习题在运算过程中不得出现负数与非整数,比如不能出 3÷5+2=2.6,2-5+10=7等算式。

  • 3 练习题生成好后,将你的学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中,不要输出额外信息,文件目录与程序目录一致。

  • 4 当程序接收的参数为4时,以下为一个输出文件示例。

      2018010203
      13+17-1=29
      11*15-5=160
      3+10+4-16=1
      15÷5+3-2=4
    

1.3 附加功能要求

  • 1 支持有括号的运算式,包括出题与求解正确答案。注意,算式中存在的括号数必须大于2对,且不得超过运算符的个数。

  • 2 扩展程序功能支持真分数的出题与运算(只需要涵盖加减法即可),例如:1/6 + 1/8 + 2/3= 23/24。注意在实现本功能时,需支持运算时分数的自动化简,比如 1/2+1/6=2/3,而非4/6,且计算过程中与结果都须为真分数。

2 项目地址

个人博客

https://linxi99.gitee.io/

https://linxi99.gitee.io/20190319/Arithmetic-Device/

https://blog.youkuaiyun.com/linxilinxilinxi

https://blog.youkuaiyun.com/linxilinxilinxi/article/details/88548481

项目地址

https://gitee.com/linxi99/four_operational_generators

3 项目源代码

#include <bits/stdc++.h>

using namespace std;

mt19937 mt(time(0));
map<int, char> op;
map<int, int> pri;

struct node{
   
   
    int id, val;
    node(int id = -1, int val = -1):id(id), val(val){
   
   }
};

int tot, operatorNum, operandNum, bracketNum, ans;
int hasBracket[15], operators[15], operands[15];
int RPN[55], fac[105];
stack<int> opr;
stack<node> opd;

void init1(){
   
   
    tot = 0;
    for(int i = 0; i < 15; ++i){
   
   
        operators[i] = -1;
        operands[i] = -1;
        hasBracket[i] = -1;
    }
    while(!opr.empty()) opr.pop();
    while(!opd.empty()) opd.pop();
}

void init2(){
   
   
    tot = 0;
    while(!opr.empty()) opr.pop();
    while(!opd.empty()) opd.pop();
}

bool getOperands(){
   
   
    init2();
    if(hasBracket[0] != -1) opr.push(hasBracket[0]);
    RPN[tot++] = 0;
//    puts("**3.1**");
    for(int i = 1; i < operandNum; ++i){
   
   
//        printf("%d\n", i);
        while(true){
   
   
            if(opr.empty() || opr.top() == 14 || pri[operators[i - 1]] > pri[opr.top()]){
   
   
                opr.push(operators[i - 1]);
                break;
            }
            RPN[tot++] = opr.top();
            opr.pop();
        }
        if(hasBracket[i] == 14){
   
   
            opr.push(hasBracket[i]);
        }
        RPN[tot++] = i;
        if(hasBracket[i] == 15){
   
   
            while(opr.top() != 14){
   
   
                RPN[tot++] = opr.top();
                opr.pop();
            }
            opr.pop();
        }
    }

//    puts("**3.2**");

    while(!opr.empty()){
   
   
        RPN[tot++] = opr.top();
        opr.pop();
    }

//    for(int i = 0; i < tot; ++i){
   
   
//        printf("%d ", RPN[i]);
//    }
//    puts("");

//    puts("**3.3**");

    for(int i = 0; i < tot; ++i){
   
   
        if(RPN[i] < 10){
   
   
            int x = mt()%66 + 1;
            operands[RPN[i]] = x;
            opd.push(node(RPN[i], x));
            continue;
        }
        if(RPN[i] == 13){
   
   
            node b = opd.top(); opd.pop();
            node a = opd.top(); opd.pop();
            if(a.val%b.val == 0){
   
   
                opd.push(node(-1, a.val/b.val));
                continue;
            }
            if(b.id == -1) return false;
            int cnt = 0;
            for(int j = 1; j <= a.val; ++j){
   
   
                if(a.val%j) continue;
                fac[cnt++] = j;
            }
            int x = mt()%cnt;
            operands[b.id] = fac[x];
            opd.push(node(-1, a.val/fac[x]));
        }else if(RPN[i] == 11){
   
   
            node b = opd.top(); opd.pop();
            node a = opd.top(); opd.pop();
            int dt = a.val - b.val;
            if(dt <= 0) return false;
            opd.push(node(-1, dt));
        }else{
   
   
            node b = opd.top(); opd.pop();
            node a = opd.top(); opd.pop();
            if(RPN[i] == 10) opd.push(node(-1, a.val + b.val));
            if(RPN[i] == 12) opd.push(node(-1, a.val*b.val));
        }
    }

//    puts("**3.4**");

    ans = opd.top().val; opd.pop();
    if(ans < 0 || ans > 1000) return false;
//    for(int i = 0; i < tot; ++i){
   
   
//        printf("%d ", RPN[i]);
//    }
//    puts("");

    return true;
}

bool solve(){
   
   
    init1();
    operatorNum = mt()%3 + 3;
    operandNum = operatorNum + 1;
    bracketNum = min((int)(operandNum/2), (int)(mt()%2 + 2));

//    printf("%d %d %d\n", operatorNum, operandNum, bracketNum);

    for(int i = 0; i < operatorNum; ++i) operators[i] = mt()%4 + 10;
    for(int i = 0; i < bracketNum*2; ++i){
   
   
        int x = mt()%operandNum;
        while(hasBracket[x] != -1) x = mt()%operandNum;
        hasBracket[x] = 0;
    }

//    puts("**1**");
    bool lf = true;
    for(int i = 1; i < operandNum; ++i){
   
   
        if(operators[i - 1] == 13){
   
   
            if(hasBracket[i] == 14){
   
   
                for(int j = 0; j < 15; ++j) hasBracket[j] = -1;
                break;
            }
            if(i < operandNum - 1 && operators[i] >= 12) return false;
        }
    }
//    puts("**2**");
    for(int i = 0; i < operandNum; ++i){
   
   
        if(hasBracket[i] == -1) continue;
        if(lf) hasBracket[i] = 14;
        else hasBracket[i] = 15;
        lf = (!lf);
    }

//    puts("**3**");

    if(!getOperands()) return false;

//    puts("**4**");

    if(hasBracket[0] != -1) printf("(");
    printf("%d", operands[0]);
    for(int i = 1; i < operandNum; ++i){
   
   
        if(operators[i - 1] == 13) printf("");
        else printf("%c", op[operators[i - 1]]);
        if(hasBracket[i] == 14) printf("(");
        printf("%d", operands[i]);
        if(hasBracket[i] == 15) printf(")");
    }
    printf("=%d\n", ans);
    return true;
}


int main(){
   
   
    op[10] = '+', op[11] = '-';
    op[12] = '*';
    op[14] = '(', op[15] = ')';
    pri[10] = 0, pri[11] = 0;
    pri[12] = 1, pri[13] = 1;
    pri[14] = 2, pri[15] = 2;
    freopen("../result.txt","w",stdout);
    int n;
    scanf("%d", &n);

    puts("2017012449");
    while(n--) while(!solve());

    return 0;
}

4 更新版本

4.1 源代码 2.0

#include <bits/stdc++.h>

using namespace std;

mt19937 mt(time(0)); // 随机数生成器

map<int, char> op; // 运算符id及其符号映射
map<int, int> pri; // 运算符id及其优先级映射
// 10表示加号   运算优先级为 0
// 11表示减号   运算优先级为 0
// 12表示乘号   运算优先级为 1
// 13表示除号   运算优先级为 1
// 14表示左括号 运算优先级为 2
// 15表示右括号 运算优先级为 2

// 运算数结构体,id为运算数的位置,val为运算数的值
struct node{
   
   
    int id, val;
    node(int id = -1, int val = -1):id(id), val(val){
   
   }
};

// tot:逆波兰表达式的长度,operatorNum:运算符个数
// operandNum:运算数的个数,bracketNum:括号对数,ans:运算式最终答案
// hasBracket:某个数字处是否有括号,-1表示无括号,14表示左括号,15表示右括号
// operators:对应位置的运算符种类 operands:表示对应位置运算数的值
// RPN:存储逆波兰表达式 fac:存储某个数的约数
// opr:中缀表达式转后缀表达式时的运算符栈
// opd:中缀表达式转后缀表达式时的运算数栈

int tot, operatorNum, operandNum, bracketNum, ans;
int hasBracket[15], operators[15], operands[15];
int RPN[55], fac[105];
stack<int> opr;
stack<node> opd;

// 初始化函数零:初始化运算符 id 符号 以及运算优先级,并且重定向输出
void init0(){
   
   
    op[10] = '+', op[11] = '-';
    op[12] = '*';
    op[14] = '(', op[15] = ')'
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值