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

        实验思路: 利用四则运算2构造的式子和数据结构中栈的应用求表达式的值计算结果。

          1.建立并初始化OPTR和OPND栈,分别存放符号和数字。

          2.依次取表达式的每个值和符号,执行3-5,知道求出最后的值。

          3.去除optr栈顶元素,与都入的进行比较,当读入#时,求解完毕。

          4.栈顶元素是数字,压opnd栈

          5.如果是符号,将符号与optr栈顶元素进行比较,如果小于,将符号压入optr,如果大于,optr出栈,做相应运算,然后将计算结果压入opnd栈,如果等于,optr栈顶元素为(,读入字符为),这时候optr出栈,继续读取下一个字符。

          根据这个算法,我们也遇到了很多问题:

          第一,我们将其调试,成功的第一步是能够运算10以内的四则运算,但是若两位数呢。

          第二,我们将程序进行改进,把char类型换为double类型,然后建立了三个数组,double a[],char b[],int clu[],分别存放操作数,运算符和对应位置应该是什么(clu[0]=1,表示第一个应该是一个数,clu[1]=2,表示此时应该为一个符号),这 样就能是操作数不再局限于一位数了。

          第三,程序可以了以后,我们又将程序编程一个字符串,将字符串分开存到三个数组里,在进行运算。根据clu数组的值,在数组a[],b[]进行取值,并运算。

    程序代码:

      1 /*
      2 结对编程《四则运算》
      3 于磊  20133078
      4 李萌  20133079 */
      5 #include <iostream>
      6 #include <string>
      7 #include <ctime>
      8 #define N 50
      9 using namespace std;
     10 void Operands_1()  /*产生操作数 (-9 -- 9)除0*/
     11 {
     12     while(int f=1)  
     13     {
     14         int Oper=rand()%19-9;
     15         if(Oper>0)             /*没有0*/
     16         {
     17             cout<<Oper;
     18             break;
     19         }
     20         if(Oper<0)
     21         {
     22             cout<<"("<<Oper<<")";
     23             break;
     24         }
     25     }
     26 }
     27 void Operands_2()/*-9到9  有0*/
     28 {
     29     while(int f=1)  /*产生操作数 (-9 -- 9)*/
     30     {
     31         int Oper=rand()%19-9;
     32         if(Oper>=0)/*有0*/
     33         {
     34             cout<<Oper;
     35             break;
     36         }
     37         else
     38         {
     39             cout<<"("<<Oper<<")";
     40             break;
     41         }
     42     }
     43 }
     44 int Operands_3() /*0-9*/
     45 {
     46     int Operand=rand()%9+1;
     47     return Operand;
     48 }
     49 string Operands_4()
     50 {
     51     string s="";
     52     int Operand=rand()%99+1;
     53     if(Operand<10)
     54     {
     55         s+=Operand+48;
     56     }
     57     else
     58     {
     59         s+=Operand/10+48;
     60         s+=Operand%10+48;
     61     }
     62     return s;
     63 }
     64 void Operator_1(string &formula)/*随机产生运算符   有乘除*/
     65 {
     66     int f=rand()%4;
     67     if(f==0) 
     68     {
     69         formula+="+";
     70     }
     71     if(f==1)
     72     {
     73         formula+="-";
     74     }
     75     if(f==2)
     76     {
     77         formula+="*";
     78     }
     79     if(f==3)
     80     {
     81         formula+="/";
     82     }
     83 }
     84 void Operator_2(string &formula)/*随机产生运算符   无乘除*/
     85 {
     86     int f=rand()%2;
     87     if(f==0) 
     88     {
     89         formula+="+";
     90     }
     91     if(f==1)
     92     {
     93         formula+="-";
     94     }
     95 }
     96 int Bracket_l(int left,string &formula) /*随机产生左括号*/
     97 {
     98     int f=rand()%3;
     99     if(f<2)
    100     {
    101         return left;
    102     }
    103     if(f==2)
    104     {
    105         formula+="(";
    106         return left+1;
    107     }
    108     return 0;
    109 }
    110 int Bracket_r(int right,string &formula) /*随机产生右括号*/
    111 {
    112     int r=rand()%5;
    113     if(r==0)
    114     {
    115         return right;
    116     }
    117     if(r>0) /*产生右括号的概率大 */
    118     {
    119         formula+=")";
    120         return right+1;
    121     }
    122     return 0;
    123 }
    124 string Way_1() /*最多可支持10个数参与计算   有乘除 有括号 10以内 加减有负数 除法有余数*/
    125 {
    126     string formula="";
    127     int length=rand()%9+2; /*随机产生表达式中操作数的个数 2-10 个*/
    128     int left=0,right=0,flag=0,left_1;
    129     for(int i=0;i<length-1;i++)
    130     {
    131         left_1=left;
    132         left=Bracket_l(left,formula);
    133         if(left_1!=left)     /*产生了左括号  flag=i*/
    134         {
    135             flag=i;
    136         }
    137         //cout<<Operands_3();
    138         formula+=Operands_4();
    139         if(left>right&&flag!=i) /*左括号大于右括号的个数 and 产生左括号和右括号不在一个循环里  即不会产生“(随机数)” 这种无效情况*/
    140         {
    141             right=Bracket_r(right,formula);
    142         }
    143         Operator_1(formula);  /*有乘除*/
    144     }
    145    // cout<<Operands_3(); /*因为 一个操作数一个运算符   还缺少一个操作数 (0 -- 9)*/
    146     formula+=Operands_4();
    147     for(int i=0;i<left-right;i++)
    148     {
    149         //cout<<")";
    150         formula+=")";
    151     }
    152    // cout<<" = "<<endl;
    153     return formula+="#";
    154 }
    155 
    156 string Way_2() /*最多可支持10个数参与计算   没乘除 有括号 10以内 加减有负数 除法有余数*/
    157 {
    158     string formula="";
    159     int length=rand()%9+2; /*随机产生表达式中操作数的个数 2-10 个*/
    160     int left=0,right=0,flag=0,left_1;
    161     for(int i=0;i<length-1;i++)
    162     {
    163         left_1=left;
    164         left=Bracket_l(left,formula);
    165         if(left_1!=left)     /*产生了左括号  flag=i*/
    166         {
    167             flag=i;
    168         }
    169         //cout<<Operands_3();
    170         formula+=Operands_4();
    171         if(left>right&&flag!=i) /*左括号大于右括号的个数 and 产生左括号和右括号不在一个循环里  即不会产生“(随机数)” 这种无效情况*/
    172         {
    173             right=Bracket_r(right,formula);
    174         }
    175         Operator_2(formula);  /*有乘除*/
    176     }
    177    // cout<<Operands_3(); /*因为 一个操作数一个运算符   还缺少一个操作数 (0 -- 9)*/
    178     formula+=Operands_4();
    179     for(int i=0;i<left-right;i++)
    180     {
    181         formula+=")";
    182     }
    183     return formula+="#";
    184 }
    185 string Way_3() /*最多可支持10个数参与计算   没乘除 有括号 10以内 加减有负数 除法有余数*/
    186 {
    187     string formula="";
    188     int length=rand()%9+2; /*随机产生表达式中操作数的个数 2-10 个*/
    189     int left=0,right=0,flag=0;
    190     for(int i=0;i<length-1;i++)
    191     {
    192         formula+=Operands_4();
    193         Operator_1(formula);  /*有乘除*/
    194     }
    195    // 因为 一个操作数一个运算符   还缺少一个操作数 (0 -- 9)*/
    196     formula+=Operands_4();
    197     return formula+="#";
    198 }
    199 string Way_4() /*最多可支持10个数参与计算   没乘除 没括号 10以内 加减有负数 除法有余数*/
    200 {
    201     string formula="";
    202     int length=rand()%9+2; /*随机产生表达式中操作数的个数 2-10 个*/
    203     int left=0,right=0,flag=0;
    204     for(int i=0;i<length-1;i++)
    205     {
    206         formula+=Operands_4();
    207         Operator_2(formula);  /*有乘除*/
    208     }
    209    // 因为 一个操作数一个运算符   还缺少一个操作数 (0 -- 9)*/
    210     formula+=Operands_4();
    211     return formula+="#";
    212 }
    213 //*****************************************************************************
    214 double jisuan(double x,double y,char oper)
    215 { 
    216     switch(oper)
    217     {
    218     case '+':
    219         {
    220             return x+y;
    221             break;
    222         } 
    223     case '-':
    224         {
    225             return x-y;
    226             break;
    227         }
    228     case '*':
    229         {
    230             return x*y;
    231             break;
    232         } 
    233     case '/':
    234         {
    235             return x/y;
    236             break;
    237         }  
    238     }
    239     return 0;
    240 }
    241 
    242 typedef struct{
    243     double *base;
    244     double *top;
    245     int stacksize;
    246 }SqStack;
    247 //初始化化栈
    248 double InitStack(SqStack &S)
    249 {
    250     S.base=new double[N];
    251     if(!S.base)
    252         exit(0);
    253     S.top=S.base;
    254     S.stacksize=N;
    255     return 1;
    256 }
    257 
    258 //入栈操作代码
    259 char push(SqStack &S,char s)
    260 {
    261     if(S.top-S.base==S.stacksize)
    262         return 0;
    263     *S.top=s;
    264     S.top++;
    265     return s;
    266 }
    267 
    268 double push1(SqStack &S,double s)
    269 {
    270     if(S.top-S.base==S.stacksize)
    271         return 0;
    272     *S.top=s;
    273     S.top++;
    274     return s;
    275 }
    276 //出栈操作代码
    277 char pop(SqStack &S)
    278 {
    279     char x;
    280     if(S.top==S.base)
    281         return 0;
    282     --S.top;
    283     x=*S.top;
    284     return x;
    285 }
    286 
    287 double pop1(SqStack &S)
    288 {
    289     double x;
    290     if(S.top==S.base)
    291         return 0;
    292     --S.top;
    293     x=*S.top;
    294     return x;
    295 }
    296 //取栈顶元素
    297 double GetTop(SqStack S)
    298 {
    299     if(S.top==S.base)
    300         exit(1);
    301     return *(S.top-1);
    302 }
    303 
    304 char precede(char ch1,char ch2)
    305 {
    306     int i,j;
    307     char a[7][7]={        //优先级对照表,依次为+ - * / ( ) #
    308         //  +   -   *   /   (   )   #
    309         '>','>','<','<','<','>','>',    // +
    310         '>','>','<','<','<','>','>',    // - 
    311         '>','>','>','>','<','>','>',    // * 
    312         '>','>','>','>','<','>','>',    // /
    313         '<','<','<','<','<','=','0',    // (
    314         '>','>','>','>','0','>','>',    //
    315         '<','<','<','<','<','0','='     // #
    316     };
    317     switch(ch1)
    318     {
    319         //优先级与矩阵匹配
    320     case '+':
    321         {
    322             i=0;
    323             break;
    324         }
    325     case '-':
    326         {
    327             i=1;
    328             break;
    329         }
    330     case '*':
    331         {
    332             i=2;
    333             break;
    334         }
    335     case '/':
    336         {
    337             i=3;
    338             break;
    339         }
    340     case '(':
    341         {
    342             i=4;
    343             break;
    344         }
    345     case ')':
    346         {
    347             i=5;
    348             break;
    349         }
    350     case '#':
    351         {
    352             i=6;
    353             break;
    354         }
    355     }
    356     switch(ch2)
    357     {
    358         //优先级与矩阵匹配
    359     case '+':
    360         {
    361             j=0;
    362             break;
    363         }
    364     case '-':
    365         {
    366             j=1;
    367             break;
    368         }
    369     case '*':
    370         {
    371             j=2;
    372             break;
    373         }
    374     case '/':
    375         {
    376             j=3;
    377             break;
    378         }
    379     case '(':
    380         {
    381             j=4;
    382             break;
    383         }
    384     case ')':
    385         {
    386             j=5;
    387             break;
    388         }
    389     case '#':
    390         {
    391             j=6;
    392             break;
    393         }
    394     }
    395     return a[i][j];
    396 }
    397 
    398 double calculate(string str)
    399 {
    400     int i=0,j=0,k=0,w=0;
    401     int s=str.length();
    402     double a[N]={0};
    403     char b[N]={0};
    404     int clu[N]={0};
    405     for(k=0;k<s;)
    406     {
    407         if(str[k]>='0'&&str[k]<='9')
    408         {
    409             while(str[k]>='0'&&str[k]<='9')
    410             {
    411                 a[i]=(a[i])*10+(str[k]-48);
    412                 k++;
    413             }
    414             i++;
    415             clu[w]=1;
    416             w++;
    417         }
    418         else
    419         {
    420             b[i]=str[k];
    421             k++;
    422             i++;
    423             clu[w]=2;
    424             w++;
    425         }
    426     }
    427     double result;
    428     i=0;
    429     SqStack optr,opnd;
    430     InitStack(optr);
    431     push(optr,'#');
    432     InitStack(opnd);
    433     push(opnd,'#');
    434     while(clu[i]!=0&&b[i]!='#'||GetTop(optr)!='#'&&i<s)
    435     {
    436         if(clu[i]==1)
    437         {
    438             push1(opnd,a[i]);
    439             //cin>>ch;
    440             i++;
    441         }
    442         else
    443             switch(precede(GetTop(optr),b[i])){
    444             case '<':
    445                 {
    446                     push(optr,b[i]);
    447                     i++;
    448                     break;
    449                 }
    450             case '>':
    451                 {
    452                     double y=pop1(opnd);
    453                     double x=pop1(opnd);
    454                     char ch=pop(optr);
    455                     result=jisuan(x,y,ch);
    456                     push1(opnd,result);
    457                     break;
    458                 }
    459             case '=':
    460                 {
    461                     pop(optr);
    462                     i++;
    463                     break;
    464                 }
    465         }
    466     }
    467     return result;
    468 }
    469 //********************************************************
    470 int main() /*主函数*/
    471 {
    472     srand((unsigned)time(0));
    473     int number=0,a,b;
    474     cout<<"------------------------------四则运算---------------------------------"<<endl;
    475     cout<<"是否有乘除:是1否0:";
    476     cin>>a;
    477     while(a!=0&&a!=1)
    478     {
    479         cout<<"输入有误!!!请重新输入:";
    480         cin>>a;
    481     }
    482     cout<<"是否有括号:是1否0:";
    483     cin>>b;
    484     while(b!=0&&b!=1)
    485     {
    486         cout<<"输入有误!!!请重新输入:";
    487         cin>>b;
    488     }
    489     if(a==1&&b==1)
    490         cout<<"最多可支持10个数参与计算  有乘除 有括号 100以内  加减有负数 除法有余数"<<endl;
    491     if(a==0&&b==1)
    492         cout<<"最多可支持10个数参与计算  无乘除 有括号 100以内  加减有负数 除法有余数"<<endl;
    493     if(a==1&&b==0)
    494         cout<<"最多可支持10个数参与计算  有乘除 无括号 100以内  加减有负数 除法有余数"<<endl;
    495     if(a==0&&b==0)
    496         cout<<"最多可支持10个数参与计算  无乘除 无括号 100以内  加减有负数 除法有余数"<<endl;
    497     cout<<"-----------------------------------------------------------------------"<<endl;
    498     cout<<"请输入题目的数量:";
    499     int nu;
    500     cin>>nu;
    501     for(int num=0;num<nu;num++)
    502     {
    503         string s;
    504         if(a==1&&b==1)
    505         {
    506             cout<<num+1<<"";
    507             s=Way_1();
    508         }
    509         if(a==0&&b==1)
    510         {
    511             cout<<num+1<<"";
    512             s=Way_2();
    513         }
    514         if(a==1&&b==0)
    515         {
    516             cout<<num+1<<"";
    517             s=Way_3();
    518         }
    519         if(a==0&&b==0)
    520         {
    521             cout<<num+1<<"";
    522             s=Way_4();
    523         }
    524         for(int i=0;i<s.length()-1;i++)
    525         {
    526             cout<<s[i];
    527         }
    528         cout<<"=";
    529         double a;
    530         cin>>a;
    531         if(a==calculate(s))
    532         {
    533             cout<<"---恭喜你!回答正确!"<<endl;
    534             number++;
    535         }
    536         else
    537         {
    538             cout<<"---很遗憾!回答错误!正确答案为:"<<calculate(s)<<endl;
    539         }
    540     }
    541     cout<<"-----------------------------------------------------------------------"<<endl;
    542     cout<<"		您一共做对了"<<number<<"道题! 所得分数为__"<<100/nu*number<<"分__"<<endl;
    543     cout<<endl;
    544     return 0;
    545 }

    运行结果:

    无括号,无乘除:

    有括号,有乘除:

    无乘除,有括号:

    实验总结: 

         编写四则运算,极大得提高了我的编程能力,和同学的结组编程能提高了我的表达和理解能力,收获很大。 

     计划:

    日期任务 听课 编写程序 查阅资料 日总计
    星期一 2   1 3
    星期二   2   2
    星期三   5   5
    星期四 2    1 3
    星期五   3   3
    星期六   4   4
    星期日        
    周总计 4 14 2

    20

    日志:

    日期 开始 结束 中断 总时间 具体活动 备注
    3/14 14:00 15:50 30 110 听课 软件工程
      16:00 17:00 无中断 60 查阅数据结构资料 查资料
    3/15 16:10 18:10 10 110 编写程序 栈的基本操作编写
    3/16 15:10 16:10 无中断 80 编程序 char类型输入,10以内运算
      18:00 19:10 无中断 70 编写程序 将产生式子与计算结果的代码结合,完成正误判断
      19:30 22:30 30 150 编写程序 修复char与int之间的转换bug
    3/17 14:00 15:50 10 100 听课 软件工程
    3/18 16:00 18:00 30 90 编程序  
    3/18 19:00 23:30 30 240 编程序  char->double转换,完成多位数的计算
    3/19 7:30 9:40 10 120 代码整合,找bug  
      9:40 10:40 60 1040min 调试+博客 写博客

    缺陷日志记录:

    日期 编号 引入阶段 排除阶段 修复时间&问题描述
    3/14        
    3/15  1 编码 编译 栈的操作返回值类型出现问题,将其转换为char
    3/16  2 编码 编译 修复char与int之间的转换bug
    3/17  3 编码 编译 char->double转换,修复小数的bug
    3/18  4 编码 编译 只能一位数的运算,添加了三个数组,解决这个bug
    3/19  4 调试 修复 解决用户输入问题,然后判断正误

    结队照片:

     

  • 相关阅读:
    AGC 015 E
    CF 1041 F. Ray in the tube
    AGC 005 D
    CF 348 D. Turtles
    2069: [POI2004]ZAW
    AGC 007 D
    zhengruioi 470 区间
    2653: middle
    Django 源码安装及使用
    Django MTV模型思想
  • 原文地址:https://www.cnblogs.com/L-Damon-v/p/5296551.html
Copyright © 2011-2022 走看看