zoukankan      html  css  js  c++  java
  • 数据结构课程设计四则运算表达式求值(C语言版)

      明人不说暗话,直接上百度网盘链接,输入提取码z3fy即可下载

        文件中包含程序,程序运行文件,设计报告和测试样例,应有尽有,欢迎小伙伴们在中下载使用。

        本课程设计为四则运算表达式求值,用于带小括号的一定范围内正负数的四则运算标准(中缀)表达式的求值。
    注意事项:
        1、请保证输入的四则表达式的合法性。输入的中缀表达式中只能含有英文符号“+”、“-”、“*”、“/”、“(”、“)”、“=”、数字“0”到“9”以及小数点“.”,输入“=”表示输入结束。例如9+(3-1)*3.567+10/2=,特别是请勿输入多余空格和中文左右括号。
        2、输入的中缀表达式默认限定长度是1001,可根据具体情况调整字符串数组的长度。
        3、请保证输入的操作数在double数据类型范围内,单个数字有效数字长度不可超过15位。本课程设计中操作数是C语言中的双精度浮点数类型。
        4、本课程设计中的运算数可以是负数,另外如果是正数可直接省略“+”号(也可带“+”号)。

     下面的程序正常运行需要在上面的百度网盘中下载相应文件,否则无法正常使用哦。

      1 /*本程序为四则运算表达式求值系统,用于计算带小括号的四则运算表达式求值。
      2 具体算法:
      3     先将字符串处理成操作单元(操作数或操作符),再利用栈根据四则运算
      4 的运算法则进行计算,最后得出结果。*/ 
      5 
      6 #include<stdio.h>
      7 #include<ctype.h>
      8 #include<stdlib.h>
      9 #include<string.h>
     10 #include<stdlib.h>
     11 #include<ctype.h>
     12 
     13 const int Expmax_length = 1001;//表达式最大长度,可根据适当情况调整 
     14 struct Ope_unit 
     15 {//定义操作单元 
     16     int    flag;//=1表示是操作数 =0表示是操作符 -1表示符号单元 
     17     char   oper;//操作符 
     18     double real;//操作数,为双精度浮点数 
     19 };
     20 
     21 void Display();//菜单
     22 void Instru(); //使用说明 
     23 int Check(char Exp_arry[]);
     24 void Evalua(); //先调用Conver操作单元化,再调用Calculate函数计算结果并输出 
     25 int  Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[]);//将字符串处理成操作单元 
     26 int  Isoper(char ch);//判断合法字符(+ - * / ( ) =)
     27 int  Ope_Compar(char ope1,char ope2);//操作符运算优先级比较 
     28 double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag);//用栈计算表达式结果 
     29 double Four_arithm(double x,double y,char oper);//四则运算 
     30 
     31 int main()
     32 {
     33     int select;
     34     while(1)
     35     {
     36         Display();
     37         printf("请输入欲执行功能对应的数字:"); 
     38         scanf("%d",&select);
     39         printf("
    ");
     40         switch(select)
     41         {
     42             case   1: Evalua(); break;
     43             case   2: Instru(); break;
     44             case   0: return 0; 
     45             default : printf("无该数字对应的功能,请重新输入
    "); 
     46                       system("pause");
     47         }
     48     }
     49     return 0;
     50 }
     51 
     52 int Check(char Exp_arry[])
     53 {//检查是否有非法字符,返回1表示不合法,0表示合法 
     54     int Explength=strlen(Exp_arry),i;
     55     for(i=0;i<Explength;i++)
     56     {
     57         if(!Isoper(Exp_arry[i]) && Exp_arry[i] != '.' && !isdigit(Exp_arry[i]))
     58         return 1;
     59         if(isdigit(Exp_arry[i]))
     60         {
     61             int Dig_number=0,Cur_positoin=i+1;
     62             while(isdigit(Exp_arry[Cur_positoin]) || Exp_arry[Cur_positoin]=='.')
     63             {
     64                 Dig_number++;
     65                 Cur_positoin++;
     66             }
     67             if(Dig_number >= 16)//最多能够计算15位有效数字 
     68             return 1;
     69         }
     70     }
     71     return 0;
     72 }
     73 
     74 void Evalua()
     75 {//先调用Conver函数将字符串操作单元化,再调用Calculate函数计算结果并输出 
     76     char Exp_arry[Expmax_length];
     77     int flag=0;//假设刚开始不合法,1表达式合法,0不合法 
     78     struct Ope_unit Opeunit_arry[Expmax_length];
     79     
     80     getchar();//吃掉一个换行符 
     81     printf("请输入四则运算表达式,以=结尾:
    "); 
     82     gets(Exp_arry);
     83     flag=Check(Exp_arry);
     84     if(flag) 
     85     printf("该表达式不合法!
    ");
     86     else
     87     {
     88         int Opeunit_count = Conver(Opeunit_arry,Exp_arry);
     89         double        ans = Calculate(Opeunit_arry,Opeunit_count,flag);
     90         if(flag)
     91         {
     92             printf("计算结果为:
    ");
     93             printf("%s%lf
    ",Exp_arry,ans);
     94         }
     95         else
     96         printf("该表达式不合法!
    ");
     97     }
     98     system("pause"); 
     99 }
    100 
    101 int  Conver(struct Ope_unit Opeunit_arry[],char Exp_arry[])
    102 {//将字符串操作单元化 
    103     int Explength=strlen(Exp_arry);
    104     int i,Opeunit_count=0;
    105     for(i=0;i<Explength;i++)
    106     {    
    107         if(Isoper(Exp_arry[i]))//是操作符 
    108         {
    109             Opeunit_arry[Opeunit_count].flag=0;
    110             Opeunit_arry[Opeunit_count++].oper=Exp_arry[i];
    111         }
    112         else//是操作数 
    113         {
    114             Opeunit_arry[Opeunit_count].flag=1;
    115             char temp[Expmax_length];
    116             int k=0;
    117             for(; isdigit(Exp_arry[i]) || Exp_arry[i]=='.' ;i++) 
    118             {
    119                 temp[k++]=Exp_arry[i];
    120             }
    121             i--;
    122             temp[k]='';
    123             Opeunit_arry[Opeunit_count].real=atof(temp);//将字符转化为浮点数
    124             
    125             //负数 
    126             if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0 
    127             && Opeunit_arry[Opeunit_count-1].oper=='-')
    128             {        
    129                 Opeunit_arry[Opeunit_count-1].flag = -1; 
    130                 Opeunit_arry[Opeunit_count].real  *= -1;
    131             }// -9 
    132             if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0 
    133             && Opeunit_arry[Opeunit_count-1].oper=='-' && Opeunit_arry[Opeunit_count-2].flag==0 
    134             && Opeunit_arry[Opeunit_count-2].oper !=')')
    135             {        
    136                 Opeunit_arry[Opeunit_count-1].flag = -1; 
    137                 Opeunit_arry[Opeunit_count].real  *= -1;
    138             }// )-9
    139             
    140             //正数 
    141             if(Opeunit_count == 1 && Opeunit_arry[Opeunit_count-1].flag==0 
    142             && Opeunit_arry[Opeunit_count-1].oper=='+')
    143             {        
    144                 Opeunit_arry[Opeunit_count-1].flag = -1; 
    145             }// +9 
    146             if(Opeunit_count >= 2 && Opeunit_arry[Opeunit_count-1].flag==0 
    147             && Opeunit_arry[Opeunit_count-1].oper=='+' && Opeunit_arry[Opeunit_count-2].flag==0 
    148             && Opeunit_arry[Opeunit_count-2].oper !=')')
    149             {        
    150                 Opeunit_arry[Opeunit_count-1].flag = -1; 
    151             }// )+9
    152             Opeunit_count++;
    153         }
    154     }
    155     /*for(i=0;i<Opeunit_count;i++)
    156     {//查看各操作单元是否正确,1是操作数,0是操作符 
    157         if(Opeunit_arry[i].flag == 1)
    158         printf("该单元是操作数为:%lf
    ",Opeunit_arry[i].real);
    159         else if(Opeunit_arry[i].flag == 0)
    160         printf("该单元是操作符为:%c
    ",Opeunit_arry[i].oper);
    161         else
    162         printf("该单元是负号符为:%c
    ",Opeunit_arry[i].oper);
    163     }*/
    164     return Opeunit_count;
    165 } 
    166 
    167 double Calculate(struct Ope_unit Opeunit_arry[],int Opeunit_count,int &flag)
    168 {//根据运算规则,利用栈进行计算 
    169     int i,dS_pointer=0,oS_pointer=0;//dS_pointer为操作数栈顶指示器,oS_pointer为操作符栈顶指示器 
    170     double Dig_stack[Expmax_length];//操作数栈(顺序存储结构) 
    171     char   Ope_stack[Expmax_length];//操作符栈 
    172     
    173     for(i=0;i<Opeunit_count-1;i++)
    174     {
    175         if( Opeunit_arry[i].flag != -1 )
    176         {
    177             if(Opeunit_arry[i].flag)//是操作数 
    178             {
    179                 Dig_stack[dS_pointer++]=Opeunit_arry[i].real;//入操作数栈 
    180                 //printf("%lf
    ",Digit[dS_pointer-1]);
    181             }
    182             else//是操作符 + - * / ( ) 
    183             {
    184                 //操作符栈为空或者左括号 入栈
    185                 if(oS_pointer==0 || Opeunit_arry[i].oper=='(')  
    186                 {
    187                     Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
    188                     //printf("%oS_pointerOpe_u_count",Operator[oS_pointer-1]);
    189                 }
    190                 else
    191                 {
    192                     if(Opeunit_arry[i].oper==')')//是右括号将运算符一直出栈,直到遇见左括号 
    193                     {
    194                         oS_pointer--;//指向栈顶 
    195                         dS_pointer--;//指向栈顶 
    196                         while(Ope_stack[oS_pointer] != '(' && oS_pointer != 0)
    197                         {
    198                             Dig_stack[dS_pointer-1] = Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer],
    199                             Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈 
    200                             
    201                             dS_pointer--;//前一个操作数出栈 
    202                             //printf("操作数栈顶元素等于%lf
    ",Digit[dS_pointer]);
    203                         }
    204                         oS_pointer--;//左括号出栈
    205                          
    206                         oS_pointer++;//恢复指向栈顶之上 
    207                         dS_pointer++;
    208                     }
    209                     else if(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer-1]))//和栈顶元素比较 
    210                      {
    211                          Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
    212                          //printf("%oS_pointerOpe_u_count",Operator[oS_pointer-1]);
    213                     } 
    214                      else//运算符出栈,再将该操作符入栈 
    215                      {
    216                          oS_pointer--;//指向栈顶 
    217                          dS_pointer--;//指向栈顶
    218                         while(Ope_Compar(Opeunit_arry[i].oper,Ope_stack[oS_pointer])==0 && oS_pointer != -1)
    219                         {//当前操作符比栈顶操作符优先级高 
    220                             Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer],
    221                             Ope_stack[oS_pointer--]);
    222                             dS_pointer--;
    223                             //printf("操作数栈顶元素等于%lf
    ",Digit[dS_pointer]);
    224                         }
    225                         oS_pointer++;//恢复指向栈顶之上  
    226                         dS_pointer++;
    227                         Ope_stack[oS_pointer++]=Opeunit_arry[i].oper;
    228                     }
    229                 } 
    230             }    
    231         }
    232     }
    233     /*for(i=0;i<oS_pointer;i++)
    234         printf("操作符栈%oS_pointerOpe_u_count",Operator[i]);
    235     for(i=0;i<dS_pointer;i++)
    236         printf("操作数栈%lf
    ",Digit[i]);*/
    237     oS_pointer--;//指向栈顶元素 
    238     dS_pointer--;//指向栈顶元素 
    239     while(oS_pointer != -1)
    240     {
    241         Dig_stack[dS_pointer-1]=Four_arithm(Dig_stack[dS_pointer-1],Dig_stack[dS_pointer],
    242         Ope_stack[oS_pointer--]);//oS_pointer--为操作符出栈 
    243         dS_pointer--;//前一个操作数出栈 
    244         //printf("操作数栈顶元素为%lfOpe_u_count",Digit[dS_pointer]);
    245     }
    246     //printf("%dS_pointer,%dS_pointer
    ",oS_pointer,dS_pointer);
    247     if(oS_pointer==-1 && dS_pointer==0)
    248         flag=1;//为1表示表达式合法 
    249     return Dig_stack[0];
    250 }
    251 
    252 int  Ope_Compar(char ope1,char ope2)
    253 {//操作符运算优先级比较
    254     char list[]={"(+-*/"};
    255     int map[5][5]={//先行后列,行比列的运算级优先级低为0,高为1 
    256     //        ( + - * /    
    257     /*  (  */ 1,0,0,0,0,
    258     /*  +  */ 1,0,0,0,0,
    259     /*  -  */ 1,0,0,0,0,
    260     /*  *  */ 1,1,1,0,0,
    261     /*  /  */ 1,1,1,0,0 };
    262     int i,j;
    263     for(i=0;i<5;i++) 
    264         if(ope1==list[i]) break;
    265     for(j=0;j<5;j++) 
    266         if(ope2==list[j]) break;
    267     return map[i][j];
    268 }
    269 
    270 double Four_arithm(double x,double y,char oper)
    271 {//四则运算 
    272     switch(oper)//保证不含其它运算符 
    273     {
    274         case '+': return x+y;
    275         case '-': return x-y;
    276         case '*': return x*y;
    277         case '/': return x/y;//y不能为0 
    278         default : return 0; 
    279     }
    280 }
    281 
    282 int  Isoper(char ch)
    283 {//判断合法字符  + - * / ( ) =
    284     if(ch=='+' || ch=='-' || ch=='*' || ch=='/' || ch=='(' || ch==')' || ch=='=') 
    285         return 1;
    286     return 0;
    287 }
    288 
    289 void Display()
    290 {//打印菜单 
    291     system("cls");
    292     printf("/******************************************************************************/
    ");
    293     printf("		       欢迎使用本四则运算表达式求值系统
    ");
    294     printf("
    	说明:建议请您先阅读使用说明,再输入相应的数字进行操作,谢谢配合!
    "); 
    295     printf("
    		1 四则运算表达式求值
    "); 
    296     printf("
    		2 使用说明
    ");
    297     printf("
    		0 退出
    "); 
    298     printf("/******************************************************************************/
    ");
    299 }
    300 
    301 void Instru()
    302 {//打印使用说明 
    303     FILE *fp;
    304     char ch;
    305     if( ( fp=fopen("使用说明.txt","r") ) == NULL)
    306     {
    307         printf("文件打开失败!
    ");
    308         exit(0); 
    309     } 
    310     for(; (ch = fgetc(fp)) != EOF; )
    311         putchar(ch);
    312     fclose(fp);
    313     printf("
    ");
    314     system("pause"); 
    315 }
  • 相关阅读:
    Oracle GoldenGate for Sql Server连接ODBC失败的处理方法
    cordova 打包出现transformClassesWithDexForDebug一类错误的解决办法
    mac下cordova的ios-deploy安装问题
    c#截取后台窗口的图片
    命令行--调用ORACLE的SQL语句
    SQL-SERVER 数据库备份 ftp 传到远程服务器 加 restore 数据库 一条龙 附源码
    google map
    怎么根据所给url进行屏幕截屏并保存为图片
    jquery mobile
    研究领域总结(二):稀疏——矩阵补全
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/8344034.html
Copyright © 2011-2022 走看看