栈操作的问题

题意:给出一个表达式,包含运算符+,-,*,min,max,求其结果

思路:用两个栈,一个操作数栈,一个操作符栈,当处理+,-,*操作符时,如果处理的操作符优先级比栈顶操作符优先级低,就入栈,否则,出栈;在处理min,max操作符时,如果当前处理的为min或者max,将min或者max,(两个入栈,当处理逗号时,就出栈,直到栈顶操作符为左括号,并将逗号入栈;而当处理右括号时,出栈直到栈顶为逗号。当处理完毕后,操作符栈可能不为空,需要出栈处理

代码如下:

#include <iostream>
#include <stack>
#include <string>
#include <map>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <fstream>

using namespace std;

const int MAX_LEN = 100;

class Solution
{
public:
	int Calculate(char *pszExpr)
	{
		map<string, int> pPriority;
		pPriority["+"] = 1;
		pPriority["-"] = 1;
		pPriority["*"] = 2;
		pPriority["("] = 0;

		stack<string> operStack;
		stack<int> numStack;

		int len = strlen(pszExpr);

		for (int i = 0; i < len; i++)
		{
			if (isspace(pszExpr[i])) continue;


			//数字
			if (isdigit(pszExpr[i]))
			{
				int j = i;
				int sum = 0;
				while (j < len && isdigit(pszExpr[j]))
				{
					sum = sum * 10 + (pszExpr[j] - '0');
					j++;
				}
				numStack.push(sum);
				i = j - 1;
				continue;
			}

			if (pszExpr[i] == '-' || pszExpr[i] == '+' || pszExpr[i] == '*')
			{
				if (operStack.empty())
				{
					string tmp;
					tmp += pszExpr[i];
					operStack.push(tmp);
				}
				else
				{
					string curOper;
					curOper += pszExpr[i];
					if (pPriority[curOper] > pPriority[operStack.top()])
					{
						operStack.push(curOper);
					}
					else
					{
					    while(!operStack.empty() && pPriority[curOper] <= pPriority[operStack.top()])
                        {
                            int ans = popCal(numStack, operStack);
                            numStack.push(ans);
                        }
                        operStack.push(curOper);
					}
				}
			}
			else if (pszExpr[i] == 'm')
			{
				char tmp[4] = { 0 };
				strncpy(tmp, &pszExpr[i], 3);
				string strtmp = tmp;
				operStack.push(strtmp);
				operStack.push("(");
				i += 3;
				continue;
			}
			else if (pszExpr[i] == ',')
			{
				while (!operStack.empty() && operStack.top() != "(")
				{
					int ans = popCal(numStack, operStack);
					numStack.push(ans);
				}
				operStack.push(",");
			}
			else if (pszExpr[i] == ')')
			{
				while (!operStack.empty() && operStack.top() != ",")
				{
					int ans = popCal(numStack, operStack);
					numStack.push(ans);
				}
				operStack.pop();//弹出,
				operStack.pop();//弹出(
				int ans = popCal(numStack, operStack);
				numStack.push(ans);
			}
		}

		while (!operStack.empty())
		{
			int ans = popCal(numStack, operStack);
			numStack.push(ans);
		}

		return numStack.top();
	}

private:
	int cal(int num1, int num2, string oper)
	{
		if (oper == "+")
		{
			return num1 + num2;
		}
		else if (oper == "-")
		{
			return num1 - num2;
		}
		else if (oper == "*")
		{
			return num1 * num2;
		}
		else if (oper == "min")
		{
			return min(num1, num2);
		}
		else if (oper == "max")
		{
			return max(num1, num2);
		}
	}

	int popCal(stack<int>& numstack, stack<string>& operstack)
	{
		int num2 = numstack.top(); numstack.pop();
		int num1 = numstack.top(); numstack.pop();
		string op = operstack.top(); operstack.pop();
		int ans = cal(num1, num2, op);

		return ans;
	}
};


验证代码如下:

1 * 2 + max(3,4)
min(2+3, max(4, 5))

int main()
{
#ifndef ONLINE_JUDGE
	ifstream fin("f:\\oj\\uva_in.txt");
	streambuf *old = cin.rdbuf(fin.rdbuf());
#endif
	Solution solver;
	char s[MAX_LEN];
	while (cin.getline(s, MAX_LEN))
	{
		cout << "s:" << s << endl;
		int ans = solver.Calculate(s);
		cout << "ans:" << ans << endl;
	}
#ifndef ONLINE_JUDGE
	cin.rdbuf(old);
#endif
	return 0;
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值