编译原理实验 逆波兰式的产生及计算

  • 实验目的

 计算逆波兰式的表达式,并且用逆波兰式进行计算。

设计方法 

实验代码:

#include<iostream>
#include<vector>
#include<string.h>
#include<stack>
#include<stdio.h>
using namespace std;

struct Item{
	int type;
	double value;
	char ch;
	Item(int t,double v){type=t;value=v;}
	Item(int t,int v){type=t;value=v;}
	Item(int t,char c){type=t;ch=c;}
};
vector<Item>polan;

int cmpch(char ch1,char ch2)
{
	int n1,n2;
	if(ch1=='(')n1=1;
	if(ch1=='+'||ch1=='-')n1=2;
	if(ch1=='*'||ch1=='/')n1=3;
	if(ch2=='(')n2=1;
	if(ch2=='+'||ch2=='-')n2=2;
	if(ch2=='*'||ch2=='/')n2=3;
	return n1-n2;
}

void printPolan()
{
	for(int i=0;i<polan.size();i++)
	{
		if(polan[i].type==1)
			cout<<polan[i].value<<"_";
		else if(polan[i].type==2)
			cout<<polan[i].ch<<"_";
	}
	cout<<endl;
}

void work()
{
	char str[100],strtmp[100];
	cin.getline(str,50,'#');
	int i,j,len=strlen(str);
	double tmp;
	char ch;
	vector<Item>ready;

	for(i=0;i<len;i++)
	{
		ch=str[i];
		if(ch==10)continue;

		if(ch>='0' && ch<='9')
		{
			sscanf(str+i,"%lf",&tmp);
			ready.push_back(Item(1,tmp));
			while(str[i]>='0' && str[i]<='9')i++;
			if(str[i]=='.')
			{
				i++;
				while(str[i]>='0' && str[i]<='9')i++;
			}
			i--;
		}
		else if(ch=='+' ||ch=='-' ||ch=='*' ||ch=='/' )
		{
			ready.push_back(Item(2,ch));
		}
		else if(ch=='(' )
		{
			ready.push_back(Item(3,ch));
		}
		else if(ch==')' )
		{
			ready.push_back(Item(4,ch));
		}
		else
		{
			cout<<"illegel char error!"<<endl;
			return ;
		}
	}


	polan.clear();
	stack<Item>sta;
	for(i=0;i<ready.size();i++)
	{
		if(ready[i].type==1)
		{
			polan.push_back(ready[i]);
		}
		else if(ready[i].type==2)
		{
			if(sta.empty()==1)
				sta.push(ready[i]);
			else
			{
				while(sta.empty()!=1 && cmpch(ready[i].ch,sta.top().ch)<0)	//比栈顶的符号优先级要小
				{
					polan.push_back(sta.top());
					sta.pop();
				}
				sta.push(ready[i]);
			}
		}
		else if(ready[i].type==3)
		{
			sta.push(ready[i]);
		}
		else if(ready[i].type==4)
		{
			while(sta.empty()!=1 && sta.top().ch!='(')
			{
				polan.push_back(sta.top());
				sta.pop();
			}
			if(sta.top().ch=='(')
				sta.pop();
			else if(sta.empty()==1)
			{
				cout<<"error!"<<endl;
				return;
			}
		}
		else
		{
			cout<<"type error!"<<endl;
			return;
		}
	}
	while(sta.empty()!=1)
	{
//		cout<<sta.top().type<<"-"<<sta.top().value<<"-"<<sta.top().ch<<endl;
		polan.push_back(sta.top());
		sta.pop();
	}
	printPolan();
}

double process(double a,double 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;
	}
}

void count()
{
	stack<double>sta;
	int i,j;
	double cur,ex;
	for(i=0;i<polan.size();i++)
	{
		if(polan[i].type==1)
			sta.push(polan[i].value);
		else
		{
			cur=sta.top();
			sta.pop();
			if(sta.empty()==1)
			{
				cout<<"stack error!"<<endl;
				return ;
			}
			ex=sta.top();
			sta.pop();
			sta.push(process(ex,cur,polan[i].ch));
		}
	}
	cout<<sta.top()<<endl;
}
int main()
{
	work();
	count();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值