zoukankan      html  css  js  c++  java
  • 四则运算3

      题目要求: 随机生成四则运算,要能判定用户输入的答案是否正确,并且能处理四则运算的混合算式。

      思路:首先产生一个随机数A,产生一个运算符x,将其存放在一个字符串(例如str)中,形成Ax形式,然后产生另外一个随机数B,也存放在str中,这样就形成了一个AxB形式的字符串,再产生一个只有0或者1的随机数,如果随机数是1就对AxB加括号,0则不加,继续产生运算符及随机数B,这个式子完毕,最后加一个‘=’号;然后就是控制加减是否有负数,如果有就重新产生四则运算的式子;在产生出所有的式子之后,用户可以输入答案,然后可以将用户输入的答案和原式所计算出来的答案比较,如果相等则计算正确,让计算做对题总数的count加1;那原式的答案是怎么计算出来的呢?利用数据结构中栈的知识,先定义运算符的优先级,然后将操作数和运算符优先级最大的入栈,栈内优先级最大的先进行计算,栈内外优先级相等则出栈;对于除不尽的将结果保留两位小数。

      具体代码如下:

      1 //第三次课堂小测验,2016/3/14
      2 //张晓菲、张哲
      3 //随机生成四则运算,可以判断用户输入是否正确以及输出做对题的总个数;处理四则运算混合算式;
      4 
      5 #include<stack>
      6 #include<iostream>
      7 #include<string>
      8 #include<sstream>
      9 #include<time.h>
     10 #include<iomanip>
     11 #include<fstream>
     12 using namespace std;
     13 
     14 int check_1(int a)//判断用户输入是否符合要求
     15 {
     16     if (a != 1 && a != 0)
     17     {
     18         cout << "输入格式不正确,请重新输入:";
     19         cin >> a;
     20     }
     21     return 0;
     22 }
     23 int check_2(int a)
     24 {
     25     if (a <= 0)
     26     {
     27         cout << "输入格式不正确,请重新输入:";
     28         cin >> a;
     29     }
     30     return 0;
     31 }
     32 
     33 string change(int num0)//将表达式转换为字符串类型
     34 {
     35     char str[100];
     36     _itoa_s(num0, str, 10);
     37     string str1 = str;
     38     return str1;
     39 }
     40 
     41 int judge(char c1, char c2)//设置+.-.*./.(.)的优先等级
     42 {
     43     int a1, a2;
     44     if ('+' == c1 || '-' == c1) a1 = 3;
     45     if ('*' == c1 || '/' == c1)a1 = 5;
     46     if ('(' == c1) a1 = 1;
     47     if (')' == c1) a1 = 7;
     48     if ('#' == c1) a1 = 0;
     49     if ('+' == c2 || '-' == c2)a2 = 2;
     50     if ('*' == c2 || '/' == c2)a2 = 4;
     51     if ('(' == c2) a2 = 6;
     52     if (')' == c2) a2 = 1;
     53     if ('#' == c2) a2 = 0;
     54     if (a1>a2) return 1;
     55     if (a1 == a2) return 0;
     56     if (a1<a2) return -1;
     57 }
     58 //符号运算函数
     59 double run(char c, double d1, double d2)//计算四则运算
     60 {
     61     switch (c)
     62     {
     63     case '+':
     64         return d1 + d2;
     65         break;
     66     case '-':
     67         return d1 - d2;
     68         break;
     69     case'*':
     70         return d1*d2;
     71         break;
     72     case '/':
     73         return d1/d2;
     74         break;
     75     default:
     76         return 0.0;
     77         break;
     78     }
     79 }
     80 double calculate(string str4)//计算表达式的值
     81 {
     82     char * op = "+-*/()#";
     83     //给表达式字符串str添加'#'结束标识符
     84     str4.append(1, '#');
     85     stack<char> OPTR;//运算符栈
     86     stack<double> OPND;//操作数栈
     87     int a = -1;
     88     //先将#符号入栈
     89     OPTR.push('#');
     90     while (true)
     91     {
     92         int b = a + 1;
     93         a = str4.find_first_of(op, a + 1);
     94         if (a == string::npos) break;
     95         if (a != b)
     96         {
     97             string ss(str4, b, a - b);
     98             double d = atof(ss.c_str());
     99             //数据先入栈
    100             OPND.push(d);
    101         }
    102         //运算符优先级比较
    103         int ju = judge(OPTR.top(), str4[a]);
    104         if (-1 == ju)//栈外优先级大直接入栈
    105         {
    106             OPTR.push(str4[a]);
    107         }
    108         if (0 == ju)//栈内外优先级相等则出栈
    109         {
    110             OPTR.pop();
    111         }
    112         if (1 == ju)//栈内优先级大,出栈进行运算
    113         {
    114             double d1 = OPND.top();
    115             OPND.pop();
    116             double d2 = OPND.top();
    117             OPND.pop();
    118             d1 = run(OPTR.top(), d2, d1);
    119             //运算结果入栈
    120             OPND.push(d1);
    121             OPTR.pop();
    122             a--;
    123         }
    124     }
    125     //删除表达式最后的'#'结束标识符
    126     str4.erase(str4.length() - 1, 1);
    127     return  OPND.top();
    128 }
    129 int main()//主函数
    130 {
    131     srand((unsigned)time(NULL));//时间种子
    132     int max, num, choose_way, choose_chengchu,choose_minus, choose_brackets;
    133     int num_suanshi;
    134     double input_result;
    135     int count = 0;
    136     int len;//求字符串长度
    137     ofstream fout("1.txt");//输出到文件
    138 
    139     cout << "请输入允许的最大数值:";
    140     cin >> max;
    141     int k = check_2(max);
    142 
    143     cout << "请输入生成的题目个数:";
    144     cin >> num;
    145     int k1 = check_2(num);
    146 
    147     cout << "请选择输出方式(1、输出到屏幕 0、输出到文件):";
    148     cin >> choose_way;
    149     int k2 = check_1(choose_way);
    150 
    151     cout << "是否有乘除法(1、有 0、没有):";
    152     cin >> choose_chengchu;
    153     int k3 = check_1(choose_chengchu);
    154 
    155     switch (choose_chengchu)
    156     {
    157     case 1:
    158 
    159         break;
    160     case 0:
    161         cout << "请选择加减是否有负数(1、有 0、没有):";
    162         cin >> choose_minus;
    163         int k5 = check_1(choose_minus);
    164         break;
    165     }
    166     
    167     cout << "请选择是否有括号(1、有 0、没有):";
    168     cin >> choose_brackets;
    169     int k6 = check_1(choose_brackets);
    170 
    171     cout<<"请选择一行输出多少个算式:";
    172     cin>>num_suanshi;
    173     char sym[4] = { '+', '-', '*', '/' };
    174     double result[1000];
    175     double result1[1000];
    176     int i;
    177     for (i = 0; i < num; i++)
    178     {
    179         int oper_num = rand() % 8 + 1;//一个式子中含有几个数
    180         string str_1, str_2_1, str_3;
    181         int num1 = rand() % (max + 1)+1;
    182         int num2 = rand() % (max + 1)+1;
    183         int d;
    184         switch (choose_chengchu)//是否有乘除
    185         {
    186         case 1:
    187             d = rand() % 4;
    188             break;
    189         case 0:
    190             d = rand() % 2;
    191             break;
    192         }
    193         str_1 = change(num1) + sym[d] + change(num2);
    194         for (int j = 0; j < oper_num; j++)
    195         {
    196             int c;
    197             int num3 = rand() % (max + 1)+1;
    198             switch (choose_chengchu)//是否有乘除
    199             {
    200             case 1:
    201                 c = rand() % 4;
    202                 break;
    203             case 0:
    204                 c = rand() % 2;
    205                 break;
    206             }
    207             str_1 = str_1 + sym[c] + change(num3);
    208             int b;
    209             b = rand() % 2;
    210             switch (choose_brackets)//判断是否有括号
    211             {
    212             case 1://有括号时随机产生括号
    213                 if (b == 0)
    214                 {
    215                     str_1 = '(' + str_1 + ')';
    216                 }
    217                 if (b == 1)
    218                 {
    219                     str_1 = str_1;
    220                 }
    221                 break;
    222             case 0://选择无括号时
    223                 break;
    224             }
    225             str_3 = str_1;
    226         }
    227         result[i]= calculate(str_3);//调用calculate函数计算四则运算表达式的结果
    228         switch (choose_chengchu)
    229         {
    230         case 1://有乘除
    231             break;
    232         case 0://没有乘除
    233             switch (choose_minus)
    234             {
    235             case 1://有负数
    236                 break;
    237             case 0://没有负数
    238             panduan :
    239                 if (result[i]<0)//加减混合运算中保证结果无负数
    240                 {
    241                     for (int j = 0; j<oper_num; j++)
    242                     {
    243                         int num2_1 = rand() % (max + 1)+1;
    244                         int d1;
    245                         d1 = rand() % 2;
    246                         str_1 = change(num2_1) + sym[d1];
    247                         str_2_1 = str_2_1 + str_1;
    248                         int num3 = rand() % (max + 1);
    249                         str_3 = str_2_1 + change(num3) ;
    250                         result[i] = calculate(str_3);
    251                         goto panduan;
    252                     }
    253                 }
    254                 break;
    255             }
    256             break;
    257         }
    258         len=sizeof(str_3);
    259         int m=40-len;
    260         result1[i]= calculate(str_3);
    261         str_3=change(i+1)+""+str_3+"=";
    262 
    263         if((int(result1[i])-result1[i])!=0)//除不尽的情况下将结果保留两位小数
    264         {
    265             result1[i]=result1[i]*100+0.5;
    266             result1[i]=int(result1[i]);
    267             result1[i]=result1[i]/100;
    268         }
    269         switch (choose_way)//选择输出方式
    270         {
    271         case 1://输出到屏幕
    272             cout.flags(ios::left);
    273             cout <<setw(40)<<str_3 ;
    274             if((i+1)%num_suanshi==0)
    275                 cout<<endl;
    276             break;
    277         case 0://输出到文件
    278             fout.flags(ios::left);
    279             fout <<setw(40)<<str_3 ;
    280             if((i+1)%num_suanshi==0)
    281                 fout<<endl;
    282             break;
    283         } 
    284     }
    285     cout<<"请输入式子的答案:"<<endl;
    286     for(i=0;i<num;i++)
    287     {
    288         cout<<i+1<<"";
    289         cin >> input_result;//用户输入的计算结果
    290         if (((result1[i]-0.05)<input_result)&&(input_result<(result1[i]+0.05)))
    291         {
    292             cout << "输入正确!" << endl;
    293             count = count + 1;
    294         }
    295         else
    296             cout << "输入错误!" << endl;
    297     }
    298     cout << "您总共做对题的个数是:";
    299     cout << count << endl;
    300     return 0;
    301 }

    运行结果如下:

      计划日志:

      计划每天用一个小时来做这次作业,每天实现一个小功能。比如第一天实现随机产生式子的功能。第二天实现随机产生括号的功能。第三天产生计算结果并判断用户输入是否正确的 功能……

      缺陷记录:

      除法无法判断是否有余数,不能查重,可能会出现题目一样的算式。

      时间记录日志:

  • 相关阅读:
    图像的卷积
    信息理论与编码中有关信源编码的笔记
    Java 数组排序
    完全平方数
    Java 作业题4
    Java 作业题3
    Java 作业题 2
    算法面试题二:旋转数组,存在重复元素,只出现一次的数字
    算法面试题一:排序算法及贪心算法
    微信小程序 发送模板消息的功能实现
  • 原文地址:https://www.cnblogs.com/quite-love/p/5295294.html
Copyright © 2011-2022 走看看