本博客介绍leetcode上的一道不难,但是比较经典的算法题。

题目如下:

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-negative integers and empty spaces .

You may assume that the given expression is always valid.

Some examples:

也可以直接参考 https://leetcode.com/problems/basic-calculator/

这是简单的加减计算运算题,一个直观的思路是运用栈,以及用后缀表达式求值。实现这一种算法,需要构造两个栈,分别是运算符栈和数字栈,然后将输入的中序表达式在转化为后续表达式的过程中求值。

考虑到这道题目的特殊性,运算符只有加减和括号,我们可以转化加减运算符为(±1),这样可以省略计算时的判断语句,而直接将转化后的运算符数作为被加(减)数的系数

这是我的代码

int calculate(string s) {
s.push_back('#'); //防止栈溢出
stack<int>num; //数字栈
stack<int>oper; //运算符栈
for(int i=; i<s.length()-;++i)
{
if(isdigit(s[i])) //判断数字,压入数字栈
{
int temp = s[i]-'';
while(++i && isdigit(s[i]))
{
temp = temp * + s[i] - '';
}
num.push(temp);
}
switch (s[i]){
case '(': //'('直接压入栈,其代表数为0
oper.push();
break;
case '+':
case '-':
if(!oper.empty() && oper.top() != ) //栈中有加减运算符,则先弹出,再压入现在的运算符
{
int num1 = num.top(); num.pop();
int num2 = num.top(); num.pop();
num.push(num2 + num1 * oper.top());
oper.pop();
}
if(s[i] == '-')
oper.push(-);
else oper.push();
break;
case ')': //为')',则一直弹出栈至弹出第一个'('
if(oper.top() == )
oper.pop();
else
{
int num1 = num.top(); num.pop();
int num2 = num.top(); num.pop();
num.push(num2 + num1 * oper.top());
oper.pop();
oper.pop();
}
break;
case '#':
break;
}
}
if(oper.empty())
return num.top();
else
{
int num1 = num.top(); num.pop();
int num2 = num.top(); num.pop();
return (num2 + num1 * oper.top());
}
}

其实这个算法的效率并不是很高,原因在于,每个数字都要压栈、退栈,每个操作符(除了')')也同样如此。

下面这个算法是讨论区上面的比较优秀的算法,其亮点是

  1. 用独立的变量存储上次的数字和加减运算符,在n次连续加减运算时省略了分别n-1次出入栈;
  2. 遇到'(',只压入前面的加减运算符,默认为加法。
class Solution {
public:
int calculate(string s) {
stack <int> nums, ops;
int num = ;
int rst = ;
int sign = ;
for (char c : s) {
if (isdigit(c)) {
num = num * + c - '';
}
else {
rst += sign * num;
num = ;
if (c == '+') sign = ;
if (c == '-') sign = -;
if (c == '(') {
nums.push(rst);
ops.push(sign);
rst = ;
sign = ;
}
if (c == ')' && ops.size()) {
rst = ops.top() * rst + nums.top();
ops.pop(); nums.pop();
}
}
}
rst += sign * num;
return rst;
}
};

也可以参考https://leetcode.com/discuss/53921/16-ms-solution-in-c-with-stacks

Basic Calculator的更多相关文章

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

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

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

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

  3. Basic Calculator II

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

  4. 数据结构与算法(1)支线任务2——Basic Calculator

    题目:https://leetcode.com/problems/basic-calculator/ Implement a basic calculator to evaluate a simple ...

  5. LeetCode#227.Basic Calculator II

    题目 Implement a basic calculator to evaluate a simple expression string. The expression string contai ...

  6. Java for LeetCode 227 Basic Calculator II

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

  7. Java for LeetCode 224 Basic Calculator

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

  8. LeetCode Basic Calculator II

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

  9. LeetCode Basic Calculator

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

随机推荐

  1. [转载]《民航科技》2012年4月专家论坛:罗喜伶《SWIM技术国际研究动态及对中国民航的借鉴意义》

    专家介绍:罗喜伶,北京航空航天大学电子信息工程学院副教授,工学博士,硕士生导师,国家空管新航行系统技术重点实验室和协同式网络化空中交通管理系统研究教育部创新团队核心成员,民航空管广域信息系统专家组成员 ...

  2. Hive On Spark hiveserver2方式使用

    启动hiveserver2: hiveserver2 --hiveconf hive.execution.engine=spark spark.master=yarn 使用beeline连接hives ...

  3. C++ 全局变量、局部变量、静态全局变量、静态局部变量的区别

    全局变量.局部变量.静态全局变量.静态局部变量的区别 C++变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为6种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作 ...

  4. sqlldr

    1.字符集 sqlldr可以指定读取的文件的字符集,如果数据库为gbk,读取的文件为utf-8,这个时候就需要指定字符集 load data CHARACTERSET 'UTF8' 2.sqlldr导 ...

  5. C#调用 ICSharpCode.SharpZipLib.Zip 实现解压缩功能公用类

    最近想用个解压缩功能 从网上找了找 加自己修改,个人感觉还是比较好用的,直接上代码如下 using System; using System.Linq; using System.IO; using ...

  6. xcode-git笔记

    git initgit add .vi .gitignore /*将代码区蓝色字体的内容*/git commit -m "初次建立"git remote add origin ht ...

  7. oracle基础语法大全

    -----创建序列create sequence book_idINCREMENT BY 1 -- 每次加几个 START WITH 001 -- 从1开始计数 NOMAXVALUE -- 不设置最大 ...

  8. JS動態綁定下拉單內容

    function req00_Line1_onChange(obj) {     //if ($(obj).val() != "" && $(obj).val() ...

  9. [CSS]多浏览器兼容的垂直居中,兼容多个IE

    相信你都是在兼容垂直居中而烦恼,翻阅多个网站总是找不到理想的方法而苦恼,来到这里你的问题解决了!如果对你有帮助请点个赞,谢谢. 多兼容垂直居中,在IE6-9亲自测试并通过 <!doctype h ...

  10. MVC下判断PC和移动端

    MVC下的PC端和移动端,其实没区别,写法都一样,只是有两点才改变了它们 第一点:就是单击这个页面任何地方的时候判断是移动端还是客户端: 第二点:新建手机端区域Areas(简单来说:Areas就相当于 ...