Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negativeintegers and empty spaces .

Example 1:

Input: "1 + 1"
Output: 2

Example 2:

Input: " 2-1 + 2 "
Output: 3

Example 3:

Input: "(1+(4+5+2)-3)+(6+8)"
Output: 23

Note:

  • You may assume that the given expression is always valid.
  • Do not use the eval built-in library function.

这道题让我们实现一个基本的计算器来计算简单的算数表达式,而且题目限制了表达式中只有加减号,数字,括号和空格,没有乘除,那么就没啥计算的优先级之分了。于是这道题就变的没有那么复杂了。我们需要一个栈来辅助计算,用个变量sign来表示当前的符号,我们遍历给定的字符串s,如果遇到了数字,由于可能是个多位数,所以我们要用while循环把之后的数字都读进来,然后用sign*num来更新结果res;如果遇到了加号,则sign赋为1,如果遇到了符号,则赋为-1;如果遇到了左括号,则把当前结果res和符号sign压入栈,res重置为0,sign重置为1;如果遇到了右括号,结果res乘以栈顶的符号,栈顶元素出栈,结果res加上栈顶的数字,栈顶元素出栈。代码如下:

解法一:

class Solution {
public:
int calculate(string s) {
int res = , sign = , n = s.size();
stack<int> st;
for (int i = ; i < n; ++i) {
char c = s[i];
if (c >= '') {
int num = ;
while (i < n && s[i] >= '') {
num = * num + (s[i++] - '');
}
res += sign * num;
--i;
} else if (c == '+') {
sign = ;
} else if (c == '-') {
sign = -;
} else if (c == '(') {
st.push(res);
st.push(sign);
res = ;
sign = ;
} else if (c == ')') {
res *= st.top(); st.pop();
res += st.top(); st.pop();
}
}
return res;
}
};

下面这种方法和上面的基本一样,只不过对于数字的处理略微不同,上面的方法是连续读入数字,而这种方法是使用了一个变量来保存读入的num,所以在遇到其他字符的时候,都要用sign*num来更新结果res,参见代码如下:

解法二:

class Solution {
public:
int calculate(string s) {
int res = , num = , sign = , n = s.size();
stack<int> st;
for (int i = ; i < n; ++i) {
char c = s[i];
if (c >= '') {
num = * num + (c - '');
} else if (c == '+' || c == '-') {
res += sign * num;
num = ;
sign = (c == '+') ? : -;
} else if (c == '(') {
st.push(res);
st.push(sign);
res = ;
sign = ;
} else if (c == ')') {
res += sign * num;
num = ;
res *= st.top(); st.pop();
res += st.top(); st.pop();
}
}
res += sign * num;
return res;
}
};

在做了Basic Calculator III之后,再反过头来看这道题,发现递归处理括号的方法在这道题也同样适用,我们用一个变量cnt,遇到左括号自增1,遇到右括号自减1,当cnt为0的时候,说明括号正好完全匹配,这个trick在验证括号是否valid的时候经常使用到。然后我们就是根据左右括号的位置提取出中间的子字符串调用递归函数,返回值赋给num,参见代码如下:

解法三:

class Solution {
public:
int calculate(string s) {
int res = , num = , sign = , n = s.size();
for (int i = ; i < n; ++i) {
char c = s[i];
if (c >= '' && c <= '') {
num = * num + (c - '');
} else if (c == '(') {
int j = i, cnt = ;
for (; i < n; ++i) {
if (s[i] == '(') ++cnt;
if (s[i] == ')') --cnt;
if (cnt == ) break;
}
num = calculate(s.substr(j + , i - j - ));
}
if (c == '+' || c == '-' || i == n - ) {
res += sign * num;
num = ;
sign = (c == '+') ? : -;
}
}
return res;
}
};

类似题目:

Basic Calculator IV

Basic Calculator III

Basic Calculator II

Evaluate Reverse Polish Notation

Different Ways to Add Parentheses

Expression Add Operators

参考资料:

https://leetcode.com/problems/basic-calculator/

https://leetcode.com/problems/basic-calculator/discuss/62361/Iterative-Java-solution-with-stack

https://leetcode.com/problems/basic-calculator/discuss/62362/JAVA-Easy-Version-To-Understand!!!!!

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Basic Calculator 基本计算器的更多相关文章

  1. [LeetCode] Basic Calculator III 基本计算器之三

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  2. [LeetCode] 224. Basic Calculator 基本计算器

    Implement a basic calculator to evaluate a simple expression string. The expression string may conta ...

  3. [LeetCode] Basic Calculator IV 基本计算器之四

    Given an expression such as expression = "e + 8 - a + 5" and an evaluation map such as {&q ...

  4. [LeetCode] Basic Calculator II 基本计算器之二

    Implement a basic calculator to evaluate a simple expression string. The expression string contains ...

  5. LeetCode Basic Calculator II

    原题链接在这里:https://leetcode.com/problems/basic-calculator-ii/ Implement a basic calculator to evaluate ...

  6. LeetCode Basic Calculator

    原题链接在这里:https://leetcode.com/problems/basic-calculator/ Implement a basic calculator to evaluate a s ...

  7. Basic Calculator 基本计算器

    2018-09-27 22:02:36 一.Basic Calculator II 问题描述: 问题求解: sign用来保存前一个符号,用num来记录数字,如果碰到一个符号或者到达结尾,则需要进行入栈 ...

  8. [LeetCode] Basic Calculator & Basic Calculator II

    Basic Calculator Implement a basic calculator to evaluate a simple expression string. The expression ...

  9. LeetCode——Basic Calculator II

    Description: Implement a basic calculator to evaluate a simple expression string. The expression str ...

随机推荐

  1. Error:const char* 类型的实参和LPCWSTR类型的形参不兼容的解决方法。

    在C++的Windows 应用程序中经常碰到这种情况. 解决方法: 加入如下转换函数: LPCWSTR stringToLPCWSTR(std::string orig) { size_t origs ...

  2. 黄聪:如何给wordpress的编辑器添加一个自定义按钮,并且实现插入功能

    1.添加按钮 在  functions.php  文件里面添加下面代码: add_action('media_buttons', 'add_my_media_button'); function ad ...

  3. scikit-learn一般实例之四:使用管道和GridSearchCV选择降维

    本例构建一个管道来进行降维和预测的工作:先降维,接着通过支持向量分类器进行预测.本例将演示与在网格搜索过程进行单变量特征选择相比,怎样使用GrideSearchCV和管道来优化单一的CV跑无监督的PC ...

  4. GridView的使用(高度封装,不怎么灵活,repeat可替代)

    GridView的使用 首先,gridview是封装好的,直接在设计界面使用,基本不需要写代码: 一.绑定数据源 GridView最好与LinQDatasourse配合使用,相匹配绑定数据: 二.样式 ...

  5. MahApps.Metro打造拉风的桌面应用程序

    官网:http://mahapps.com/ github:https://github.com/MahApps/MahApps.Metro

  6. DataGridView绑定源码下载

    效果图: 源码下载:http://hovertree.com/h/bjaf/bbot18bj.htm 上面源码不包含数据库的查询,需要获取数据库数据的话,请看这个的源码: http://hovertr ...

  7. screen命令

    基本用法 screen -S testname 在这里面执行命令,即使终端突出,进程也不会断掉 screen -list查看有哪些screen screen -r testname 恢复

  8. 如何在Spring MVC Test中避免”Circular view path” 异常

    1. 问题的现象 比如在webConfig中定义了一个viewResolver public class WebConfig extends WebMvcConfigurerAdapter { //配 ...

  9. Redis主从复制

    大家可以先看这篇文章ASP.NET Redis 开发对Redis有个初步的了解 Redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此 ...

  10. 浏览器对localstorage的支持情况以及localstorage在saas系统中的应用实践思考

    首先,还是要说,任何一种新特性的引入,通常有着其特有的场景和解决的目标需求,localstorage也一样.在我们的应用场景中,主要在金融业务服务的saas系统.其中涉及很多更改频率很多的元数据的客户 ...