简单的中缀表达式转后缀表达式

简单的中缀表达式转后缀表达式

这里的简单指的是表达式简单,所有数字都是个位数,不是代码简单

中缀表达式就是我们平时最经常使用的,例:(1+2)*3-4
后缀表达式就是把运算符放到运算数后面
后缀表达式传送门

后缀表达式计算传送门

转换思路

  • 假设输入的中缀表达式的字符串为 str
  • 需要一个栈 s 来作为临时的先进后出的存储结构
  • 需要一个字符串 result 来保存最终的结果
  • 从左到右遍历中缀表达式,按照一定的规则将不同的运算符或数字加入到 s 或者 result中

具体规则为:
规定当前读取的 str[i] 的某一个字符为 c

  1. 如果c是数字,直接加入结果串 result 中
  2. 如果c是左括号(,直接加入栈 s 中
  3. 如果c是右括号),逐步倒出栈中的符号,并将他们加入结果串 result 中,直到栈顶出现左括号(,然后倒出这个左括号
  4. 如果c是运算符,比较c与栈顶元素的优先关系,如果优先,则直接进栈,否则逐步倒出栈中元素并加入结果串 result ,直到遇到栈顶元素优先级低于c,将c进栈

代码

在这里插入图片描述

#include <iostream>
#include <string>
#include <stack>
#include <map>

using namespace std;

#define char2int(x) ((int)(x - '0'))
#define int2char(x) ((char)(x + '0'))

// 使用map结构存储运算符的优先级别
typedef pair<char, int> p;
map<char, int> m;
void minit()
{
	// #号防止空栈,故优先为最低
	m.insert(p('#', -1));
	m.insert(p('+', 1));
	m.insert(p('-', 1));
	m.insert(p('*', 2));
	m.insert(p('/', 2));
}

int main()
{
	string str;
	cin>>str;
	
	// 栈中加入一个'#'防止空栈 
	stack<char> s;
	s.push('#');
	
	// 结果串,map初始化 
	string result = "";
	minit();
	
	// 从左到右遍历中缀表达式串
	for(int i=0; i<str.length(); i++)
	{
		char c = str[i];
		if('0'<=c && c<='9')
		{
			result += c;
		}
		else if(c == '(')
		{
			s.push(c);
		}
		else if(c == ')')
		{
			while(s.top() != '(')
			{
				result += s.top();
				s.pop();
			}
			s.pop();
		}
		else 
		{
			while(1)
			{
				if(s.top()=='(' || m[s.top()]<m[c])
				{
					break;
				}
				result += s.top();
				s.pop();
			}
			s.push(c);
		}
	}
	
	while(s.top() != '#')
	{
		result += s.top();
		s.pop();
	}
	
	cout<<result<<endl;
	 
	return 0;
}



表达式树

  • 运算数字放在叶子节点,符号放在根节点
  • 一个根节点代表一个运算的结果
  • 一个根节点的运算结果可以递归地表示为:

左子树的运算结果 运算 右子树的运算结果

  • 后序遍历表达式树,得到后缀表达式
    在这里插入图片描述
    在这里插入图片描述
发布了53 篇原创文章 · 获赞 4 · 访问量 5241

猜你喜欢

转载自blog.csdn.net/weixin_44176696/article/details/104090330