【LeetCode224】-简单计算器

题目大意

输入一系列的字符串,进行模拟计算器的计算,只不过这个计算器比较简单只涉及到加减和括号的运算,在里面还会有空格干扰
之前做过类似的题目要带上乘除运算(不过程序被我不小心删掉了)

实现思路:

使用的数据结构栈:

  1. 数据栈
  2. 操作符栈

状态转换

借鉴别人的思想系统的说,在这个过程中会有两种状态的转换

下一个字符为操作符
下一个字符为数字
处理数字
处理操作符

可以使用一个state变量来标识

  • 当处于处理数字状态下,将例如12的字符串转换为12数值类型的元素
    • 同时判断下该数值转换是否已经恰好完成,即下一个状态为处理操作符状态,或者整个字符串已经结束。若果已经恰好完成或整个字符串处理到最后一位,将该数值压入栈中。再判断下cmp_flag是否为1,如果为1,则 从数据栈弹出两个元素,操作符栈弹出一个元素,进行计算,并将结果压入栈中。
  • 当处于处理操作符状态下
    • 如果为’( ',设置计算标识cmp_flag=0
    • 如果为’)’ 表明现在立即可以进行计算
    • 如果为其他操作符,设置计算标识cmp_flag=1,并且将操作符压入操作符栈中

可以在处理状态操作之前判断当前字符是否为空格,如果为空格直接continue即可

实现代码

#include <stack>
#include <iostream>
#include <cctype>
using namespace std;

const int BEGIN = 0;
const int NUMBER = 1;
const int OPERA = 2;
long long compute(stack<long long>& data, stack<char>& opera,int flag) {
	long num2 = data.top();data.pop();
	long num1 = data.top();data.pop();
	char op = opera.top();opera.pop();
	if (op == '+') {
		return num1 + num2;
	}
	else if (op == '-') {
		if (flag)
			return num1 - num2;
		else
			return num2 - num1;
	}
	return 0;
}
class Solution {
public:
	int state;
	int cmp_flag;
	stack<long long> data;
	stack<char>opera;
	Solution() {
		state = BEGIN;
		cmp_flag = 0;
	}
	int calculate(string s) {
		long long num = 0;
		for (int i = 0;i < s.length();i++)
		{
			if (s[i] == ' ')continue;
			if (isdigit(s[i]))
				state = NUMBER;
			else
				state = OPERA;
			switch (state) {
			case NUMBER: {
				num = num * 10 + s[i] - '0';
				if ((i + 1 < s.length() && !isdigit(s[i + 1])) || i + 1 == s.length()) {
					data.push(num);
					if (cmp_flag && data.size() >= 2)
					{
						data.push(compute(data, opera,1));
					}
					num = 0;
				}
				break;
			}
			case OPERA: {
				if (s[i] == '(')
					cmp_flag = 0;
				else
				{
					cmp_flag = 1;
					if (s[i] != ')')
					{
						opera.push(s[i]);
						if (i == 0)
							data.push(0);
					}
					else {
						if(data.size()>=2)
						data.push(compute(data, opera, 1));
					}
				}
				break;
			}
			}
		}
		stack<long long>tdata;
		stack<char> topera;
		
		if (!opera.empty()) {
			while (!data.empty()) { tdata.push(data.top());data.pop(); }
			while (!opera.empty()) { topera.push(opera.top());opera.pop(); }
			while(!topera.empty())
				tdata.push(compute(tdata, topera,0));
			if (!tdata.empty()) data.push(tdata.top());
		}
		if (data.empty()) return 0;
		return data.top();
	}



};
int main() {
	Solution s;
	int sum=s.calculate("(1+(4+5+2)-3)+(6+8)");
	cout << sum<<endl;
	return 0;
}
        }

另一种实现的代码

在这里插入图片描述

踩过的坑:

  • -2+1
    • 这种情况下最开始没有考虑,后来改进当压入的第一个字符为操作符时,在数据栈压入一个0
  • 数值超过int类型最大值
    • 当时没注意数值范围,只看到给的接口,函数返回值是int,后来在计算过程中都用的long long,最后返回的是int
  • 不要忘记只有数据栈的元素≥2才可进行运算
  • 按照我的方法处理的相当于是第一轮,实际上还有可能栈中还有元素,剩下的元素按照之前输入的顺序依次算即可,但我实现的有一些些麻烦,将栈中元素导了出来再计算,在利用我写的额外计算的函数,在相减的时候还要颠倒相减才可以,实在是有些繁琐
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值