您的位置:首页 > 其它

逆波兰表达式

2015-09-01 16:46 337 查看
逆波兰表达式又叫做后缀表达式。它的语法规定,表达式必须以逆波兰表达式的方式给出。

正常的表达式 逆波兰表达式

a+b ---> a,b,+

a+(b-c) ---> a,b,c,-,+

a+(b-c)*d ---> a,b,c,-,d,*,+

a+d*(b-c)--->a,d,b,c,-,*,+

a=1+3 ---> a=1,3 +

(1-2)*(3+6)---> 1,2,-,3,6,+,*

利用栈的知识,可以将逆波兰表达式的值求出。



代码:目前只能计算0-9以内的包含括号的加减乘除,十几二十甚至浮点数的计算有待进一步开发

主要问题是:一个字符串存储逆波兰表达式,包含数字,和字符,很难统一到一起。还有数据长度的问题,目前的代码统一是1位,这样最容易实现。

#include <iostream>
#include <string>
#include <stack>
using namespace std;
#define maxsize 100

// 获取操作符的优先级
int precedence(char op)
{
	switch(op)
	{
		case '^':
		 return 3;
    
		case '*':
		case '/':
		case '%':
		 return 2;
   
		case '+':
		case '-':
		 return 1;
   
		case '(':
		 return 0;
	}
}

//判断是否是操作符 
int IsOperator(char ch)
{
	switch(ch)
	{
		case '^':
		case '*':
		case '/':
		case '%':
		case '+':
		case '-':
		 return 1;
   
		default:
		 return 0;
	}
}

// 转换
void exchange(char *pSource, char *pDest)
{
	char oper[maxsize]; // 定义操作符栈
	int top = -1; // 初始化栈定位置
	char ch;
	if(pSource==NULL || pDest==NULL)
		return;
	oper[++top] = '('; // ‘(' 初始化栈
	while((ch = *pSource++) != '#')
	{
		if(ch == '(') // '(' 直接入栈
		{
			oper[++top] = ch;
		}
		else if(ch == ')') // 运算符出栈拷入目标数组,直到'('
		{
			while(oper[top] != '(')
			{
				 *pDest++ = oper[top--];
			}
			top--;
		}
		else if(IsOperator(ch)) 
		{
			if(precedence(ch) > precedence(oper[top])) // 优先级大与栈顶字符,直接入栈
			{
				oper[++top] = ch;
			}
			else // 优先级小与栈顶字符,所有优先级大的字符拷入目标数组,再入栈
			{
				while(precedence(oper[top]) >= precedence(ch))
				{
					*pDest++ = oper[top--];
				}
				oper[++top] = ch;
			}
		}
		else // 不是运算符直接拷入目标数组
		{
			*pDest++ = ch;
		}
	}
	while(top != 0) // 源数组遍历完毕,栈中操作符拷入目标数组
	{
	   *pDest++ = oper[top--];
	}
	*pDest = '#';
}
int calculate(char *c,int len)//根据逆波兰表达式,求解值
{
	stack<int> s;//声明一个栈
	int i=0;
	int p;
	int m=0,n=0;
	while(i<len)
	{
		if(c[i]=='+'||c[i]=='-'||c[i]=='*'||c[i]=='/')
		{
			m=s.top();
			s.pop();
			n=s.top();
			s.pop();
			if(c[i]=='+')
			{
				s.push(m+n);
			}
			if(c[i]=='-')
			{
				s.push(n-m);
			}
		   if(c[i]=='*')
			{
				s.push(m*n);
			}
			if(c[i]=='/')  
			{
				s.push(n/m);
			}
		}
		else
		{
			p=c[i]-'0';
			s.push(p);
		}
		i++;
	}
	if(s.size()!=1)
	{
		cout<<"表达式错误"<<endl;
		return 0;
	}
	return s.top();
}

int main()
{
	string s;
	getline(cin,s);
	char X[maxsize];
	int i=0;
	int len=s.length();
	for(i=0;i<len;i++)
	{
		X[i]=s[i];
	}
	X[i]='#';
	//"3*2^(4+2*2-1*3)-5#";
	char B[maxsize];
	exchange(X, B);
	for(i=0; B[i]!='#'; i++)
	{
		cout<<B[i];
	}
	cout<<endl;
	//以上是给了例子求逆波兰表达式,比如(1-2)*(4+5)输出 12-45+*
	//以下是根据逆波兰表达式求值
	int lenb=i;
	cout<<calculate(B,lenb)<<endl;
	return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: