基于栈的后缀算术表达式求值

(这是一个菜鸡的19秋季学期数据结构实验课) 基于栈的后缀算术表达式求值
【实验目的】
1.掌握中缀表达式转换为后缀表达式的算法。
2.掌握后缀表达式求值的算法。
【实验内容】
问题描述
输入一个中缀算术表达式,将其转换为后缀表达式,然后对后缀表达式进行求值。运算符包括“+”、“-”、"*"、“/"、“=”,参与运算的为小于10的自然数(只考虑二元运算即可。
输入要求
多组数据,每组数据一行,对应一个算术表达式,每个表达式均以“=”结尾。当表达式只有一个“=”时,输入结東。
输出要求
对于每组数据输出2行,第1行为中缀表达式对应的后缀式,第2行为后缀式求值的结果。
输入样例
9+(3-1)*3+1/2=
1+2=

输出样例
931-3*+12/+
15
12+
3
【实验提示】
首先借助一个运算符栈将中缀表达式转换为后缀表达式,然后再借助一个运算数栈对后缀表达式求值。中缀表达式转换为后缀表达式的算法思路附后。
对转换后得到的后缀表达式进行计算的具体步骤如下:
借助一个工作栈OPND,用以寄存操作数或运算结果。从左到右扫描后缀表达式。读入第一个字符ch。若ch不是运算符,则压入OPND栈,读入下一字符;若是运算符,则从OPND中依次弹出两个数分别到Y和X,然后以”X ch Y“的形式计算出结果,将结果压 OPND栈中。如果后缀表达式未读完,重复执行上面过程,最后OPND栈顶元素即为表达式的求值结果,返回此元素

#include<stdio.h>
#include<stack>
#include<stdlib.h>
#include<iostream>
#include<ctype.h>
#include<string.h>
using namespace std;
int pre(char c)//优先级判断
{
    if(c=='=') return 0;
    else if(c=='+'||c=='-')
        return 1;
    else if(c=='*'||c=='/')
    return 2;
    else return 0;
}

int calculate(int a,int b,char ch)//运算
{
    
    switch(ch)
    {
    case '+':return a+b;
    break;
    case '-':return a-b;
    break;
    case '*':return a*b;
    break;
    case '/':return a/b;
    break;
    }
    
}

int main()
{
    stack <int> num;//存储数字 
    stack <char> op;//存储操作符 
    char s[10];
    char a[10];//存储后缀表达式 
    int r=0;
  
    while(1)//可多次输入式子 
    {
    	int i=0,t=0;
    	scanf("%s",s);//读取整个字符串 
       if(!strcmp(s,"="))//唯一的循环出口 
        break;
        for(i=0;s[i]!='\0';i++)
        {
        	
        	if(isdigit(s[i]))
        	{
        	    
        		a[t]=s[i];
        		t++;
        		
			}
			else
			{
	          if(op.empty()||s[i]=='(')//空栈或为左括号,进栈 
				op.push(s[i]);
			   else if(s[i]==')')//出栈直到左括号 
			   {
			   		while(op.top()!='('){
					
					a[t]=op.top();
					op.pop();
					t++;
				       }
				       op.pop();
			   }
			   else if(	pre(s[i])<=pre(op.top()))//总是弹出优先级大的 
			   {
			   	a[t]=op.top();
				t++;
			   	op.pop();
			   	while(pre(s[i])<=pre(op.top())&&op.empty()!=1)
			   	{
			   			a[t]=op.top();
			   			t++;
			   	        op.pop();
			   	        
				   }
				   
				   op.push(s[i]);
			
			   }
			   	 else if(pre(s[i])>pre(op.top()))
			   	 {
					op.push(s[i]);
				}
				
		     }
		}
		
		while(!op.empty())//将栈中剩下的字符存储到a中 
		{
			
			a[t]=op.top();
		    op.pop();
			t++;
		}
		
        int n=0;
         while(t--)//输出 
   {
		
        cout<<a[n];
        n++;
    }
    cout<<endl;
     
   while(1)//计算 
  {     if(a[r]=='=') break;
  
    	else if(isdigit(a[r]))
    	{
    		num.push(a[r]-48);//一开始出现严重错误,字符1在asc表中为49,忽略了字符 数字之间的问题,
			                  //浪费很长时间 
		}
		
		else 
		{
			char o=a[r];
			int c=num.top();
			num.pop();
			int d=num.top();
			num.pop();
			int x=calculate(d,c,o);
			num.push(x);
			
		}
		r++;
	}
    cout<<num.top()<<endl;
    num.pop();
	}
	
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值