后缀表达式计算
2015-08-05 21:04
387 查看
将中缀表达式转换为后缀表达式:
与转换为前缀表达式相似,遵循以下步骤:
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从左至右扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5) 遇到括号时:
(5-1) 如果是左括号“(”,则直接压入S1;
(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
(6) 重复步骤(2)至(5),直到表达式的最右边;
(7) 将S1中剩余的运算符依次弹出并压入S2;
(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。
与转换为前缀表达式相似,遵循以下步骤:
(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
(2) 从左至右扫描中缀表达式;
(3) 遇到操作数时,将其压入S2;
(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:
(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;
(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);
(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;
(5) 遇到括号时:
(5-1) 如果是左括号“(”,则直接压入S1;
(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;
(6) 重复步骤(2)至(5),直到表达式的最右边;
(7) 将S1中剩余的运算符依次弹出并压入S2;
(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<stack> using namespace std; //后缀表达式表达式求值 char a[1010]; char b[1010]; stack <char> s1; //储存运算符的栈 stack <float> s2; //储存值的栈 int i,j,n,m,t; float x,y,z; int fun(char x) //比较优先级 { switch(x) { case '+' : case '-' : return 1; case '*' : case '/' : return 2; case '(' : return 0; default : return -1; } } float js(float x,float y,char z) //运算 { switch(z) { case '+': return y+x; case '-': return y-x; case '*': return y*x; default : return y/x; } } int main() { int p; char c[1010]; float d; // scanf("%d",&t); s1.push('#'); while(~scanf("%s",a)) //循环输入 { j=0; m=strlen(a)-1; for(i=0; i<m; i++) //将中缀表达式转化为后缀表达式 { if(a[i]>='0'&&a[i]<='9'||a[i]=='.') { memset(c,0,sizeof(c)); p=0; while(a[i]>='0'&&a[i]<='9'||a[i]=='.') //将数字部分截取 { b[j++]=a[i]; c[p++]=a[i++]; } d=atof(c); //将字符串转化为浮点型 s2.push(d); //进栈 i--; } else if(a[i]=='(') s1.push(a[i]); else if(a[i]==')') //依次弹出a栈顶的运算符,并压入b,直到遇到左括号为止,将这一对括号丢弃 { while(s1.top()!='(') { b[j++]=s1.top(); x=s2.top(); s2.pop(); y=s2.top(); s2.pop(); x=js(x,y,b[j-1]); s2.push(x); s1.pop(); } s1.pop(); } else { while(fun(s1.top())>=fun(a[i])) // 比较其与a栈顶运算符的优先级 { b[j++]=s1.top(); x=s2.top(); s2.pop(); y=s2.top(); s2.pop(); x=js(x,y,b[j-1]); s2.push(x); s1.pop(); } s1.push(a[i]); } } while(s1.top()!='#') //计算 { b[j++]=s1.top(); x=s2.top(); s2.pop(); y=s2.top(); s2.pop(); x=js(x,y,b[j-1]); s2.push(x); s1.pop(); } b[j]='='; b[j+1]='\0'; puts(b); //输出后缀表达式 printf("%.2f\n",s2.top()); //输出值 默认保留两位小数 s2.pop(); //出栈 } return 0; }
相关文章推荐
- uva 10158 War (并查集)
- 最小生成树
- (剑指Offer)面试题56:链表中环的入口结点
- leetcode 76: Minimum Window Substring
- shell字符串截取操作
- LeetCode(12)Integer to Roman
- C/C++经典算法精华整理(4)-位字段输出二进制数据
- Android 4.4 Graphic Architecture
- mybatis 多对多映射关系
- LeetCode(12)Integer to Roman
- java中的包以及内部类的介绍
- Rescue
- Python文档中if __name__ == '__main__'
- Search in Rotated Sorted Array(leetcode)
- myeclipse中的SpringMVC项目创建(引入velocity框架)
- property 中的strong 与weak
- 我知道点redis-数据结构与对象(链表)
- 虚拟机字节码执行引擎
- HDOJ 5352 MZL's City 匈牙利匹配
- iOS开发---轮播图模块(连续循环滚动版)