227基本计算器 II(栈——先入栈后计算、先计算后入栈)

1、题目描述

实现一个基本的计算器来计算一个简单的字符串表达式的值。

字符串表达式仅包含非负整数,+, - ,*,/ 四种运算符和空格  。 整数除法仅保留整数部分。

说明:

  • 你可以假设所给定的表达式都是有效的。
  • 不要使用内置的库函数 eval

2、示例

输入: "3+2*2"
输出: 7

3、题解

简化版:栈+istringstream,先入栈后计算,因为*/优先级高于+-,只有知道后一个符号是什么前面的符号才能计算结果

解法一:

基本思想:栈,先计算再入栈的思想,nums保存数字的栈,sigh保存符号的栈

  • 如果遇到数字,先判断前一个符号,如果是加减,则数字入栈,因为后面可能是乘除不能直接计算;如果是乘除,直接计算结果
  • 如果遇到加减,计算前一个符号的结果
  • 如果遇到乘除,符号入栈

解法二:

基本思想:栈,优化,先入栈再计算的思想,这个问题的关键是先乘除后加减,只有知道后一个符号是什么前面的符号才能计算结果。所以设一个变量pre_op保存前一个符号,先把乘除法的值计算出来,最终将所有的运算简化成只有加法。

#include<iostream>
#include<vector>
#include<algorithm>
#include<stack>
using namespace std;
class Solution {
public:
    int calculate(string s) {
        stack<char> flag;
        stack<int> nums;
        istringstream ss(s);
        int num;
        char c;
        ss>>num;
        nums.push(num);
        while(ss>>c)
        {
            ss>>num;
            if(c=='*')
                nums.top()*=num;
            else if(c=='/')
                nums.top()/=num;
            else
            {
                if(!flag.empty())
                {
                    char f=flag.top();
                    flag.pop();
                    int num1=nums.top();
                    nums.pop();
                    int num2=nums.top();
                    nums.pop();
                    int tmp=f=='+'?num1+num2:num2-num1;
                    nums.push(tmp);
                }
                nums.push(num);
                flag.push(c);
            }
        }
        if(!flag.empty())
        {
            char f=flag.top();
            flag.pop();
            int num1=nums.top();
            nums.pop();
            int num2=nums.top();
            nums.pop();
            int tmp=f=='+'?num1+num2:num2-num1;
            nums.push(tmp);
        }
        return nums.top();
        
    }
};
class Solution {
public:
    int calculate(string s) {
		//简化版:栈,先入栈后计算,因为*/优先级高于+-,只有知道后一个符号是什么前面的符号才能计算结果
        istringstream is(s);
        stack<int> st;
        int res=0,num;
        char c,pre_op='+';
        while(is>>num)
        {
            is>>c;
            if(pre_op=='+')
                st.push(num);
            else if(pre_op=='-')
                st.push(-num);
            else if(pre_op=='*')
                st.top()*=num;
            else if(pre_op=='/')
                st.top()/=num;
            pre_op=c;
        }
        while(!st.empty())
        {
            res+=st.top();
            st.pop();
        }
        return res;
    }
};
class Solution1 {
public:
	int calculate(string s) {
		//基本思想:栈,先计算再入栈的思想,nums保存数字的栈,sigh保存符号的栈
		//如果遇到数字,先判断前一个符号,如果是加减,则数字入栈,因为后面可能是乘除不能直接计算;如果是乘除,直接计算结果
		//如果遇到加减,计算前一个符号的结果
		//如果遇到乘除,符号入栈
		stack<int> nums;
		stack<char> sigh;
		int i = 0;
		while (i < s.size() || !sigh.empty())
		{
			if (i == s.size())
			{
				int a = nums.top(); nums.pop();
				int b = nums.top(); nums.pop();
				int temp = sigh.top() == '+' ? b + a : b - a;
				sigh.pop();
				nums.push(temp);
			}
			if (isdigit(s[i]))
			{
				int num = 0;
				while (isdigit(s[i]))
				{
					num *= 10;
					num += s[i] - '0';
					i++;
				}
				if(sigh.empty())
				    nums.push(num);
				else
				{
					if(sigh.top() == '+' || sigh.top() == '-')
						nums.push(num);
					else
					{
						int a = nums.top(); nums.pop();
						int temp = sigh.top() == '*' ? a * num : a / num;
						sigh.pop();
						nums.push(temp);
					}
				}
				continue;
			}
			else if (s[i] == '-'|| s[i] == '+')
			{
				if (sigh.empty())
					sigh.push(s[i]);
				else
				{
					int a = nums.top(); nums.pop();
					int b = nums.top(); nums.pop();
					int temp = sigh.top() == '-' ? b - a : b + a;
					sigh.pop();
					sigh.push(s[i]);
					nums.push(temp);
				}
			}
			else if (s[i] == '*' || s[i] == '/')
			{
				sigh.push(s[i]);
			}
			i++;
		}
		return nums.top();
	}
};
class Solution2 {
public:
	int calculate(string s) {
		//基本思想:栈,优化,先入栈再计算的思想,这个问题的关键是先乘除后加减,只有知道后一个符号是什么前面的符号才能计算结果
		//所以设一个变量pre_op保存前一个符号,先把乘除法的值计算出来,最终将所有的运算简化成只有加法
		s += '#';    //占位,为了最后一个数字也能被计算
		stack<int> nums;
		char pre_op = '+';
		int num = 0, res = 0;
		for (int i = 0; i < s.size(); i++)
		{
			if(s[i] == ' ')
				continue;
			else if (isdigit(s[i]))
			{
				num *= 10;
				num += s[i] - '0';
			}
			else
			{
				switch (pre_op)
				{
				case '+':
					nums.push(num);
					break;
				case '-':
					nums.push(-num);
					break;
				case '*':
					nums.top() *= num;
					break;
				case '/':
					nums.top() /= num;
					break;
				}
				pre_op = s[i];
				num = 0;
			}
		}
		while (!nums.empty())
		{
			res += nums.top();
			nums.pop();
		}
		return res;
	}
};
int main()
{
	Solution1 solute;
	string s = " 3+5 / 2 ";
	cout << solute.calculate(s) << endl;
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值