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

原理:

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

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

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

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

代码(局限用整数,因为有模运算,若要任何类型的代码,我的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!='\0')      //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!='\0')
 86     while (op.data[op.top]!='=')
 87     //此时exp扫描完毕,退栈到'='为止
 88     {
 89         postexp[i++]=op.data[op.top];
 90         op.top--;
 91     }
 92     postexp[i]='\0';    //给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!='\0')    //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("\n\t除零错误!\n");
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\n",exp);
164     printf("后缀表达式:%s\n",postexp);
165     printf("表达式的值:%g\n",compvalue(postexp));
166     return 0;
167 }

 

posted @ 2016-05-15 01:21  MrPat  阅读(1441)  评论(0编辑  收藏  举报