前缀、中缀、后缀表达式归纳

后缀表达式求值:

后缀表达式是无需进行处理可以直接被计算机处理的表达式,运算符通常位于操作数的后面,例如: 3 4 + 5 * 6 -   ,它是由中缀表达式(3 + 4) × 5 - 6转换过来的

后缀表达式进行求值时,设立一个栈s1,从左到右依次访问表达式中的元素,如果遇到数字直接压入栈中,如果遇到运算符就将栈中最上方的两个元素取出后进行相应的运算,将运算结果压入栈中。具体c++代码如下:

#include "stdafx.h"
#include <iostream>
#include <stack>
#include <string>

using namespace std;


/*后缀表达式*/
int main()
{
	string s;
	getline(cin,s);        //这里需要注意,因为输入的后缀表达式操作数与运算符之间有空格隔开,因此不能用cin或者scanf进行读入
	int len = s.size();     // cin或者scanf读入时,遇到空格就会判定为结束
	printf("%d\n",s.size());
	int a,b;
	stack<int> t;
	int i;
	for (i = 0;i < len;i++)
	{
		if (s[i] == '+' ||s[i] == '-' ||s[i] == '*' ||s[i] == '/' )
		{
			if (s[i] == '+')
			{
				a = t.top();
				t.pop();
				b = t.top();
				t.pop();
				a = a + b;
				t.push(a);
			}
			else if (s[i] == '-')
			{
				a = t.top();
				t.pop();
				b = t.top();
				t.pop();
				a = b - a;
				t.push(a);
			}
			else if (s[i] == '*')
			{
				a = t.top();
				t.pop();
				b = t.top();
				t.pop();
				a = a * b;
				t.push(a);
			}
			else if (s[i] == '/')
			{
				a = t.top();
				t.pop();
				b = t.top();
				t.pop();
				a = b / a;
				t.push(a);
			}
			i++;
		}
		else
		{
			int sum = 0;
			while (s[i] != ' ')//十位数以上
			{
				sum *= 10;
				sum += (s[i] - '0');//string s
				i++;
			}
			t.push(sum);
		}
	}
	printf("%d",t.top());
	getline(cin,s);  
}

  1.  

中缀表达式转换成后缀表达式


中缀表达式在求值时往往要先转换成相对应的后缀表达式,具体的做法是

1.设立两个栈t1,t2,分别用来存放运算符和操作数

2.从左至右扫描中缀表达式;

3.遇到操作数时,将其压入t2;
4.遇到运算符时,进行如下处理:
4-1.如果t1为空,或栈顶运算符为左括号“(”,或者该运算符为'(',则直接将此运算符入栈;
4-2.如果运算符为‘)’,那么依次将t1中的运算符弹出,压入t2,直到遇到一个‘(’,将它消除;

4-3.否则,将它与栈顶的运算符的优先级进行比较:

4-3-1.如果它的优先级大于栈顶运算符优先级,那么直接压入t1;

4-3-2.如果它的优先级小于栈顶运算符优先级,那么依次将t1中的运算符弹出,压入t2,直到遇见比它优先级小的,或者栈空,或者遇到‘(’,将它压入t1;

5.依次遍历完整个中缀表达式,栈t2中存放的就是所求的后缀表达式;


#include "stdafx.h"
#include <iostream>
#include <stack>
#include <string>

using namespace std;


/*前缀表达式*/
int main()
{
	string s;
	getline(cin,s);        //这里需要注意,因为输入的后缀表达式操作数与运算符之间有空格隔开,因此不能用cin或者scanf进行读入
	int len = s.size();     // cin或者scanf读入时,遇到空格就会判定为结束
	printf("%d\n",s.size());
	int a,b;
	stack<int> t;
	int i;
	for (i = 0;i < len;i++)
	{
		if (s[i] == '+' ||s[i] == '-' ||s[i] == '*' ||s[i] == '/' )
		{
			if (s[i] == '+')
			{
				a = t.top();
				t.pop();
				b = t.top();
				t.pop();
				a = a + b;
				t.push(a);
			}
			else if (s[i] == '-')
			{
				a = t.top();
				t.pop();
				b = t.top();
				t.pop();
				a = b - a;
				t.push(a);
			}
			else if (s[i] == '*')
			{
				a = t.top();
				t.pop();
				b = t.top();
				t.pop();
				a = a * b;
				t.push(a);
			}
			else if (s[i] == '/')
			{
				a = t.top();
				t.pop();
				b = t.top();
				t.pop();
				a = b / a;
				t.push(a);
			}
			i++;
		}
		else
		{
			int sum = 0;
			while (s[i] != ' ')//十位数以上
			{
				sum *= 10;
				sum += (s[i] - '0');//string s
				i++;
			}
			t.push(sum);
		}
	}
	printf("%d",t.top());
	getline(cin,s);  
}


前缀表达式求值:

前缀表达式求值和后缀表达式求值方法很相似,只不过前缀表达式求值是从右往左扫描表达式,遇到操作数则压入栈中,遇到运算符则弹出两个操作数计算结果后重新压入

中缀表达式转前缀表达式:

与中缀转后缀相似,只说明一下不同点:

1.中缀转前缀是从右到左扫描

2.在中缀转后缀中,如果运算符比栈顶运算符的优先级高,则压入栈中,否则要依次弹出运算符栈中的元素,直到栈顶元素优先级比它低;而在中缀转前缀时,这一规则改变为如 果运算符比栈顶运算符的优先级高或它们的优先级相等,则压入栈中。

posted @ 2018-07-05 19:18  lightmare  阅读(790)  评论(0编辑  收藏  举报