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

原理:

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 }
时间: 2024-10-12 15:40:41

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

中缀表达式转换成后缀表达式

中缀表达式即普通的运算式子,运算符是以中缀形式处于操作数的中间(例:3 + 4),后缀表达式就是逆波兰式(例:3 4 +),中缀表达式转后缀表达式也是学习数据结构中的栈的时候一个典型的例子,结合上一次写到逆波兰式.可以用这种原理即输入普通式子(即中缀表达式),转换成后缀表达式,然后通过后缀表达式(逆波兰式)的计算,可以得出结果. 1 #include <stdio.h> 2 #include <stdlib.h> 3 #define STACK_INIT_SIZE 20 4 #de

中缀表达式转换成后缀表达式并求值

算法: 中缀表达式转后缀表达式的方法: 1.遇到操作数:直接输出(添加到后缀表达式中) 2.栈为空时,遇到运算符,直接入栈 3.遇到左括号:将其入栈 4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出. 5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈 6.最终将栈中的元素依次出栈,输出. 例如 a+b*c+(d*e+f)*g ----> abc*+de*f+g*+ 遇到a:直接输出: 后缀表达式:a 堆栈:空 遇到

将中缀表达式转换成后缀表达式

中缀表达式(标准形式):A+(B-C/D+E)*F 后缀表达式(便于计算机计算):ABCD/-E+F*+ 本文使用栈来实现中缀表达式到后缀表达式的转换. 操作数:A B C D E F 操作符:+ - / * ( ) 操作符优先级:( )  >  / *  >  + - 逐个字符读取中缀表达式,结果不断输出,利用栈对操作符进行缓存: 1. 遇到操作数直接输出 2. 遇到操作符,如果此操作符优先级大于栈顶操作符,则将此操作符压栈,否则输出栈顶操作符:如遇到),则把栈内操作符依次弹出,直到(,()

表达式树—中缀表达式转换成后缀表达式(一)

算法: 中缀表达式转后缀表达式的方法:1.遇到操作数:直接输出(添加到后缀表达式中)2.栈为空时,遇到运算符,直接入栈3.遇到左括号:将其入栈4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出.5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈6.最终将栈中的元素依次出栈,输出.例如a+b*c+(d*e+f)*g ----> abc*+de*f+g*+ 遇到a:直接输出:后缀表达式:a堆栈:空 遇到+:堆栈:空,所以+

3-6 中缀表达式转换成后缀表达式

1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\xtgmath.h(214): warning C4602: #pragma pop_macro:"new"该标识符前面没有 #pragma push_macro1>e:\极速考拉下载目录\vs2013(visual studio 2013旗舰版)\vc\include\xtgmath.h(215): warning C4193: #pragma warning(p

数据结构实验之栈二:一般算术表达式转换成后缀式

数据结构实验之栈二:一般算术表达式转换成后缀式 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之. 输入 输入一个算术表达式,以'#'字符作为结束标志. 输出 输出该表达式转换所得到的后缀式. 示例输入 a*b+(c-d/e)*f# 示例输出 ab*cde/-f*+ 提示 来源 示例程序 由一般是求后缀式: 1.设立暂时存放运算符的栈: 2.设表达式的结束符为"#

数据结构实验之栈与队列二:一般算术表达式转换成后缀式

数据结构实验之栈与队列二:一般算术表达式转换成后缀式 Description 对于一个基于二元运算符的算术表达式,转换为对应的后缀式,并输出之. Input 输入一个算术表达式,以‘#’字符作为结束标志. Output 输出该表达式转换所得到的后缀式. Sample Input a*b+(c-d/e)*f# Output ab*cde/-f*+ #include <stdio.h> #include <stdlib.h> char s[100005]; //分配栈的大小 int m

八、通过中缀计算表达式转换成后缀计算表达式

前言:中缀表达式符合人们的阅读习惯:  如:5+3 后缀表达式符合计算机的运算习惯:如:53+ 现在通过栈对运算符号的入栈.出栈操作实现将中缀表达式转化成后缀表达式 1.LinkList.h #ifndef _LINKLIST_H_ #define _LINKLIST_H_ typedef void LinkList; typedef struct _tag_LinkListNode LinkListNode; struct _tag_LinkListNode { LinkListNode* n

中缀表达式转换前\后缀表达式的总结

本次个人程序设计要求做一个带有计算功能的程序,而要计算就离不开表达式,按照一般人的习惯,中缀表达式是一个非常常用的方式.但是,对于我们程序员来说,直接计算中缀表达式并不是那么方便,因此,通常来说我们会将中缀表达式进行转换. 不论是转成前缀表达式还是后缀表达式,通过树进行转换都是可以实现的,同时,一棵树就能完成前\中\后缀表达式的互相转换,因此如果仅仅要求转换并且频繁的转换,建立一棵树无疑是方便的.但是,对于计算而言,转换只是其中的一步,因此我们更要考虑效率问题,那么堆栈法就成了我们的首选.堆栈是