中缀表达式转后缀表达式,以及后缀表达式的计算


在这里插入图片描述


先上题目链接
牛客:中缀转后缀

leetcode:后缀表达式计算

中缀转后缀表达式

准备三个容器:

  • vector<string> ret 存放最后结果
  • stack<char> symbol 运算符暂时存放
  • map<char,int> P 存放符号优先级

逻辑

开始遍历中缀字符串:

  1. 遇到 数字 直接存放入于输出数组 ret
  2. 遇到操作符
  • symbol栈为空 或者 当前操作符为(,直接入栈

  • 栈不为空 判断symbol栈顶运算符与当前运算符的优先级:

    • 当前运算符优先级高,则当前运算符入symbol栈,随后遍历后续字符。
    • 栈顶运算符优先级高,则出栈存入ret中,再继续判断栈顶与当前运算符优先级(如栈已空则当前运算符直接入栈)。
  • 当前运算符为 ( 直接如symbol栈。

  • 当前运算符为 ) ,则将栈顶元素依次存入ret中,直到遇到(。此时(出栈抛弃,)也舍弃不做处理。

3.遍历结束,将symbol栈中剩余元素,依次出栈存入ret中。

4.完成中缀转后缀,ret的存放顺序即为后缀顺序。

在这里插入图片描述

代码演示

vector<string> infixtosuffix()
{
	string mid;
	cin >> mid;
	vector<string> ret;//返回的字符串
	map<char, int> P;//符号优先级
	P['('] = P[')'] = 0;
	P['+'] = P['-'] = 1;
	P['*'] = P['/'] = 2;
	stack<char> symbol;//符号栈

	size_t i = 0;
	while (i < mid.size())
	{
		if (isalnum(mid[i]))
		{
			string tmp;
			while (i < mid.size() && isalnum(mid[i]))
			{
				tmp += mid[i];
				i++;
			}
			ret.push_back(tmp);//遇数字直接输出至ret
		}

		while (i < mid.size() && !symbol.empty() && P[mid[i]] <= P[symbol.top()] && mid[i] != '(')//当前符号的优先级小于等于栈顶符号则出栈
		{
			if ((mid[i] == ')') && (symbol.top() == '('))
			{
				symbol.pop();//不保留左括号
				i++;//舍弃右括号
			}
			else
			{
				ret.push_back(string(1, symbol.top()));
				symbol.pop();
			}
		}
		if (i < mid.size())
		{
			symbol.push(mid[i]);
			i++;
		}

	}
	while (!symbol.empty())
	{
		ret.push_back(string(1, symbol.top()));
		symbol.pop();
	}
	for(size_t i=0;i<ret.size();++i)
    {
        cout<<ret[i];
    }
    cout<<endl;
	return ret;
}

后缀表达式计算

准备一个容器

  • stack<int> s; 存放数字

逻辑

  • 操作数入栈,
  • 遇到操作符
  • 连拿两个操作数运算(栈顶为右操作数,出栈,此时栈顶为左操作数)
  • 运算结果压栈
  • 最后的栈顶元素则为计算结果

⚠ 注意字符与数字的转换

代码演示

int reverse_poland_cal(vector<string>& tokens)
{
	//操作数入栈,
	//遇到操作符
	//连拿两个操作数运算
	//运算结果压栈

	stack<int> s;
	for (size_t i = 0; i < tokens.size(); ++i)
	{
		if (tokens[i] == "+"
			|| tokens[i] == "-"
			|| tokens[i] == "*"
			|| tokens[i] == "/")
		{
			int  right = s.top();
			s.pop();
			switch (tokens[i][0])//switch只判断整型,需提取字符
			{
			case '+':
				s.top() += right;
				break;
			case '-':
				s.top() -= right;
				break;
			case '*':
				s.top() *= right;
				break;
			case '/':
				s.top() /= right;
				break;
			}
		}
		else
		{
			s.push(stoi(tokens[i]));
		}
	}
	return s.top();
}

青山不改 绿水长流

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值