中缀表达式转后缀表达式(逆波兰式)

        将string类型的中缀表达式转换为string类型的后缀表达式。其中,中缀表达式中,含有空格,数字(有负数),运算符+-*/,括号。我希望能得到一个用空格隔开数字和运算符的后缀表达式。

思路:用一个栈来存运算符和括号。用string ans表示最终输出。用哈希表来初始化运算符优先级。

首先,初始化ans为“0 ”,即0+空格,这是为了防止中缀表达式中第一个数字为负数,如果大家知道怎么计算后缀表达式的话,就能明白,加个0在前面,假如是负数“-1”,就会变成“0-1”,结果是一样的,不这样做的话,后面就得加判断条件,挺麻烦的。同样的,‘(’后面,要是第一个数字是负数,也得加个0,但正数就不能加。

接着,开始从string s的下标0开始遍历:

        遇到空格’ ‘,就跳过;

        遇到’(‘,就将它进栈,并且又要判断,下一个(还得跳过空格)是不是负数,假如是负数的话,又要在ans处加个‘0 ’,也就是0+空格;

        遇到‘)’,就开始将栈中运算符弹出,加到ans后面,直到栈顶为‘(’时停止,别忘了最后将‘(’弹出;

        遇到运算符,当栈为空,或者,栈顶为‘(’,或者,当前运算符优先级大于栈顶运算符时,直接将当前运算符进栈。否则,意味着,当前运算符优先级不大于栈顶的运算符,比如s[i] == '+',而栈顶运算符为‘/’,那就把栈顶运算符弹出,加到ans后面。接着当前运算符再比较一次,直到入栈。

        遇到数字,那就通过循环,把连续的数字加到ans后面。

最后,循环结束,将栈中剩余的运算符弹出,加到ans后面。就ok了

输入:" 2 +3* ( 2+1)+4"

输出:0 2 3 2 1 + * + 4 +

class Solution04 {
public:
	stack<char> op;

	string mid2rpn(string s) {
        //初始加0
		string res = "0 ";
        //哈希表初始化优先级
		unordered_map<char, int> mark = {
			{'+',1},{'-',1},{'*',2},{'/',2}
		};

		for (int i = 0; i < s.size(); i++) {
			if (s[i] == ' ') {
				continue;
			}
			else if (s[i] == '(') {
				op.push('(');
				int j = i + 1;
				while (s[j] == ' ') {
					j++;
				}
				if (s[j] == '-') {
					res += '0 ';
				}
			}
			else if (s[i] == ')') {
				while (op.top() != '(') {
					res += op.top();
					res += ' ';
					op.pop();
				}
				op.pop();
			}
			else if (s[i] == '+' || s[i] == '-' || s[i] == '*' || s[i] == '/') {
				if (op.empty() || op.top() == '(' || mark[op.top()] < mark[s[i]]) {
					op.push(s[i]);
				}
				else {
					res += op.top();
					res += ' ';
					op.pop();
                    //这里i--,是因为for循环里,每次循环i都要+1,这样就跳到下一个字符了
                    //但这里,当前运算符还需要再比较,直到入栈
					i--;
				}
			}
			else {
				while (i < s.size() && s[i] >= '0'&&s[i] <= '9') {
					res += s[i];
					i++;
				}
				res += ' ';
                //这里i--,是因为前面的while循环里的i++,跳出循环时,已经到下一个字符了
				i--;
			}
			
		}
		while (!op.empty()) {
			res += op.top();
			op.pop();
		}

		return res;
	}
};

 输出结果:

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值