zoukankan      html  css  js  c++  java
  • 后缀表达式做计算器程序

    概念:

    后缀表达式是相较于中缀表达式而言的,像我们平时写的2+3*(4-(5+6))/7就是一个中缀表达式,那么如何将之变为后缀表达式呢?后缀表达式如何用来求解呢?

    先来第一个问题(中缀->后缀):

    变为后缀表达式方法(规则)

    1.遇到操作数:直接添加到后缀表达式中

    2.栈为空时,遇到运算符,直接入栈

    3.遇到左括号:将其入栈

    4.遇到右括号:执行出栈操作,并将出栈的元素输出,直到弹出栈的是左括号,左括号不输出。

    5.遇到其他运算符:加减乘除:弹出所有优先级大于或者等于该运算符的栈顶元素,然后将该运算符入栈。

    6.最终将栈中的元素依次出栈,输出。

     

    用一个实例来分析:

    X = 2+3*(4-(5+6))/7

    1、遇到操作数2,添加到后缀表达式中                                                             2 (此时的后缀表达式,下同)

    2、栈为空,遇到加号‘+’,将‘+’入栈                                                          2

    3、遇到操作数3,添加到后缀表达式中                                                             23

    4、遇到操作符‘*’,栈顶为‘+’‘*’优先级大于‘-’,不出栈,‘*’入栈         23

    5、遇到左括号,直接入栈。                                                                        23

    6、遇到操作数4,添加到后缀表达式中                                                             234

    7、遇到减号‘-’,栈顶为‘-’入栈                                                                   234

    8、遇到左括号,直接入栈。                                                                         234

    9、遇到操作数5,添加到后缀表达式中                                                              2345

    10、遇到加号‘+’,栈顶为‘(’, ‘+’入栈                                                      2345

    11、遇到操作数6,添加到后缀表达式中                                                            23456

    12、遇到右括号’(不入栈),出栈‘+’,出栈(不添加到后缀表达式中)      23456+

    13、遇到右括号’(不入栈),出栈‘-’,出栈(不添加到后缀表达式中)       23456+-

    14、遇到‘/’,栈顶为‘*’ ‘/’优先级大于‘*’,将‘*’出栈                                              23456+-*

    15、遇到操作时7,添加到后缀表达式中                                                            23456+-*7

    16、把栈中剩下的符号都出栈                                                                             23456+-*7/+

     

     

     

    代码实现:

    char* postfix_expression(string str)
    {
    	char *temp=new char(100);
    	int j=0;
    	for(int i=0; i<str.size(); i++)
    	{
    		if(str[i]>='0' && str[i]<='9')
    			temp[j++]=str[i];
    		else
    		{
    			if(str[i]==')')
    			{
    				while(S_c.top()!='(')
    				{
    					temp[j++] = S_c.top();
    					S_c.pop();
    				}
    				S_c.pop();
    			}
    			//如果符号是*或/高优先级,弹出所有*和/ 
    			else if(str[i]=='*'||str[i]=='/')
    			{
    				if(!S_c.empty())
    					if(S_c.top()=='*'||S_c.top()=='/')
    					{
    						temp[j++] = S_c.top();
    						S_c.pop();
    					}
    				S_c.push(str[i]);
    			}
    			//如果符号是+或-低优先级,弹出所有*/+- 
    			else if(str[i]=='+'||str[i]=='-')
    			{
    				if(!S_c.empty())
    					if(S_c.top()=='*'||S_c.top()=='/'||S_c.top()=='+'||S_c.top()=='-')
    					{
    						temp[j++] = S_c.top();
    						S_c.pop();
    					}
    				S_c.push(str[i]);
    			}
    			else
    				S_c.push(str[i]);	
    		}
    	}
    	while(!S_c.empty())
    	{
    		temp[j++] = S_c.top();
    		S_c.pop();
    	}
    	return temp;
    }
    

      

    第二个问题,如何使用后缀表达式来解表达式

    后缀表达式已经将计算的优先顺序排好,只需要将后缀表达式的数字逐个入栈,直到遇到符号,将前栈顶两个元素运算放回栈顶即可。

    以上面的后缀表达式为例:

    23456+-*7/+

     

    上代码~

    #include <iostream>
    #include <string>
    #include <cstring>
    #include <stack>
    using namespace std;
    
    stack<int> S_n;
    stack<char> S_c;
    
    //上面的后缀表达式转换函数 char* postfix_expression(string str); int main() { string str; char *pe; int temp; cin>>str; //将str转为后缀表达式 pe = postfix_expression(str); for(int i=0; i<strlen(pe); i++) { if(pe[i]>='0'&&pe[i]<='9') { S_n.push(pe[i]-'0'); } else if(pe[i]=='*') { temp = S_n.top(); S_n.pop(); temp *= S_n.top(); S_n.pop(); S_n.push(temp); } else if(pe[i]=='/') { temp = S_n.top(); S_n.pop(); temp = S_n.top()/temp; S_n.pop(); S_n.push(temp); } else if(pe[i]=='+') { temp = S_n.top(); S_n.pop(); temp += S_n.top(); S_n.pop(); S_n.push(temp); } else if(pe[i]=='-') { temp = S_n.top(); S_n.pop(); temp = S_n.top()-temp; S_n.pop(); S_n.push(temp); } } cout<<pe<<endl; cout<<S_n.top()<<endl; return 0; }

    运行结果:

  • 相关阅读:
    适用于IE的自适应大小并且自动居中的对话框页面(javaScript)
    ASP.net后台动态加载JS文件
    分层就是分工与协作
    用Response.Filter生成静态页[要注意并发问题]
    新旧身份证合法性验证及验证算法
    子窗口刷新父窗口的问题
    获取字符串的真实长度
    子窗口刷新父窗口然后关闭
    datalist的数据绑定事件收藏
    通过Response.Filter属性实现网站内容的动态GZIP压缩
  • 原文地址:https://www.cnblogs.com/kamicoder/p/8593627.html
Copyright © 2011-2022 走看看