zoukankan      html  css  js  c++  java
  • 运用栈把算术表达式+,-,*,/,%(中缀表达式)转换成后缀表达式并且计算出值

    原理:

    1.首先判断是数值还是符号,如果是数值放进字符数组以#表示结束,

    2.如果是符号,放进栈,

    3.每个符号之间要比较优先级,如果栈顶符号优先级低,符号进栈,如果相等(即“(” “)”)出栈,栈顶符号优先级高,栈顶元素出栈进入字符数组,得到后缀表达式

    4.计算后缀表达式,判断是数字还是符号。直到遇到符号,将前面的数字计算后放进栈,一直重复,知道“”

    代码(局限用整数,因为有模运算,若要任何类型的代码,我的blog有)

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include  <iostream>
      4 using namespace std;
      5 #define MaxOp 100
      6 #define MaxSize 100
      7 struct  //设定运算符优先级
      8 {
      9     char ch;   //运算符
     10     int pri;   //优先级
     11 }
     12 lpri[]= {{'=',0},{'(',1},{'*',5},{'/',5},{'%',5},{'+',3},{'-',3},{')',6}},
     13 rpri[]= {{'=',0},{'(',6},{'*',4},{'/',4},{'%',4},{'+',2},{'-',2},{')',1}};
     14 int leftpri(char op)    //求左运算符op的优先级
     15 {
     16     int i;
     17     for (i=0; i<MaxOp; i++)
     18         if (lpri[i].ch==op)
     19             return lpri[i].pri;
     20 }
     21 int rightpri(char op)  //求右运算符op的优先级
     22 {
     23     int i;
     24     for (i=0; i<MaxOp; i++)
     25         if (rpri[i].ch==op)
     26             return rpri[i].pri;
     27 }
     28 bool InOp(char ch)       //判断ch是否为运算符
     29 {
     30     if (ch=='(' || ch==')' || ch=='+' || ch=='-'
     31             || ch=='*' || ch=='/'||ch=='%')
     32         return true;
     33     else
     34         return false;
     35 }
     36 int Precede(char op1,char op2)  //op1和op2运算符优先级的比较结果
     37 {
     38     if (leftpri(op1)==rightpri(op2))
     39         return 0;
     40     else if (leftpri(op1)<rightpri(op2))
     41         return -1;
     42     else
     43         return 1;
     44 }
     45 void trans(char *exp,char postexp[])
     46 //将算术表达式exp转换成后缀表达式postexp
     47 {
     48     struct
     49     {
     50         char data[MaxSize]; //存放运算符
     51         int top;            //栈指针
     52     } op;               //定义运算符栈
     53     int i=0;                //i作为postexp的下标
     54     op.top=-1;
     55     op.top++;                  //将'='进栈
     56     op.data[op.top]='=';
     57     while (*exp!='')      //exp表达式未扫描完时循环
     58     {
     59         if (!InOp(*exp))        //为数字字符的情况
     60         {
     61             while (*exp>='0' && *exp<='9') //判定为数字
     62             {
     63                 postexp[i++]=*exp;
     64                 exp++;
     65             }
     66             postexp[i++]='#';   //用#标识一个数值串结束
     67         }
     68         else    //为运算符的情况
     69             switch(Precede(op.data[op.top],*exp))
     70             {
     71             case -1:           //栈顶运算符的优先级低:进栈
     72                 op.top++;
     73                 op.data[op.top]=*exp;
     74                 exp++;     //继续扫描其他字符
     75                 break;
     76             case 0:        //只有括号满足这种情况
     77                 op.top--;      //将(退栈
     78                 exp++;     //继续扫描其他字符
     79                 break;
     80             case 1:             //退栈并输出到postexp中
     81                 postexp[i++]=op.data[op.top];
     82                 op.top--;
     83                 break;
     84             }
     85     } //while (*exp!='')
     86     while (op.data[op.top]!='=')
     87     //此时exp扫描完毕,退栈到'='为止
     88     {
     89         postexp[i++]=op.data[op.top];
     90         op.top--;
     91     }
     92     postexp[i]='';    //给postexp表达式添加结束标识
     93 }
     94 
     95 float compvalue(char exp[]) //计算后缀表达式的值
     96 {
     97     struct
     98     {
     99         int data[MaxSize];    //存放数值
    100         int top;            //栈指针
    101     } st;               //定义数值栈
    102     float d;
    103     char ch;
    104     int t=0; //t作为exp的下标
    105     st.top=-1;
    106     ch=exp[t];
    107     t++;
    108     while (ch!='')    //exp字符串未扫描完时循环
    109     {
    110         switch (ch)
    111         {
    112         case'+':
    113             st.data[st.top-1]=st.data[st.top-1]+st.data[st.top];
    114             st.top--;
    115             break;
    116         case '-':
    117             st.data[st.top-1]=st.data[st.top-1]-st.data[st.top];
    118             st.top--;
    119             break;
    120         case '*':
    121             st.data[st.top-1]=st.data[st.top-1]*st.data[st.top];
    122             st.top--;
    123             break;
    124         case '%':
    125             st.data[st.top-1]=st.data[st.top-1]%st.data[st.top];
    126             st.top--;
    127             break;
    128         case '/':
    129             if (st.data[st.top]!=0)
    130                 st.data[st.top-1]=st.data[st.top-1]/st.data[st.top];
    131             else
    132             {
    133                 printf("
    	除零错误!
    ");
    134                 exit(0);  //异常退出
    135             }
    136             st.top--;
    137             break;
    138         default:
    139             d=0; //将数字字符转换成数值存放到d中
    140             while (ch>='0' && ch<='9')   //为数字字符
    141             {
    142                 d=10*d+ch-'0';
    143                 ch=exp[t];
    144                 t++;
    145             }
    146             st.top++;
    147             st.data[st.top]=d;
    148         }
    149         ch=exp[t];
    150         t++;
    151     }
    152     return st.data[st.top];
    153 }
    154 
    155 int main()
    156 {
    157     int i=0;
    158     char exp[10];
    159     printf("请输入数学表达式:");
    160     scanf("%s",exp);
    161     char postexp[MaxSize];
    162     trans(exp,postexp);
    163     printf("中缀表达式:%s
    ",exp);
    164     printf("后缀表达式:%s
    ",postexp);
    165     printf("表达式的值:%g
    ",compvalue(postexp));
    166     return 0;
    167 }
  • 相关阅读:
    Anaconda 换国内源、删源最全集锦(转载)
    【2019】安装anaconda及环境变量的配置(安装第三方库测试)(转载)
    python 中 urlparse 模块介绍
    正则表达式之前瞻后顾
    indows下如何安装python第三方库lxml
    Ubuntu下开启SSH服务 vs:18
    Linux终端访问网页
    关于ubuntu无线网络配置
    SQL语句报错,无法绑定由多个部分组成的标识符解决
    "@P0"附近有语法错误解释及定位修复
  • 原文地址:https://www.cnblogs.com/biyongyao/p/5494350.html
Copyright © 2011-2022 走看看