本博客介绍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),这样可以省略计算时的判断语句,而直接将转化后的运算符数作为被加(减)数的系数

这是我的代码

  1. int calculate(string s) {
  2. s.push_back('#'); //防止栈溢出
  3. stack<int>num; //数字栈
  4. stack<int>oper; //运算符栈
  5. for(int i=; i<s.length()-;++i)
  6. {
  7. if(isdigit(s[i])) //判断数字,压入数字栈
  8. {
  9. int temp = s[i]-'';
  10. while(++i && isdigit(s[i]))
  11. {
  12. temp = temp * + s[i] - '';
  13. }
  14. num.push(temp);
  15. }
  16. switch (s[i]){
  17. case '(': //'('直接压入栈,其代表数为0
  18. oper.push();
  19. break;
  20. case '+':
  21. case '-':
  22. if(!oper.empty() && oper.top() != ) //栈中有加减运算符,则先弹出,再压入现在的运算符
  23. {
  24. int num1 = num.top(); num.pop();
  25. int num2 = num.top(); num.pop();
  26. num.push(num2 + num1 * oper.top());
  27. oper.pop();
  28. }
  29. if(s[i] == '-')
  30. oper.push(-);
  31. else oper.push();
  32. break;
  33. case ')': //为')',则一直弹出栈至弹出第一个'('
  34. if(oper.top() == )
  35. oper.pop();
  36. else
  37. {
  38. int num1 = num.top(); num.pop();
  39. int num2 = num.top(); num.pop();
  40. num.push(num2 + num1 * oper.top());
  41. oper.pop();
  42. oper.pop();
  43. }
  44. break;
  45. case '#':
  46. break;
  47. }
  48. }
  49. if(oper.empty())
  50. return num.top();
  51. else
  52. {
  53. int num1 = num.top(); num.pop();
  54. int num2 = num.top(); num.pop();
  55. return (num2 + num1 * oper.top());
  56. }
  57. }

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

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

  1. 用独立的变量存储上次的数字和加减运算符,在n次连续加减运算时省略了分别n-1次出入栈;
  2. 遇到'(',只压入前面的加减运算符,默认为加法。
  1. class Solution {
  2. public:
  3. int calculate(string s) {
  4. stack <int> nums, ops;
  5. int num = ;
  6. int rst = ;
  7. int sign = ;
  8. for (char c : s) {
  9. if (isdigit(c)) {
  10. num = num * + c - '';
  11. }
  12. else {
  13. rst += sign * num;
  14. num = ;
  15. if (c == '+') sign = ;
  16. if (c == '-') sign = -;
  17. if (c == '(') {
  18. nums.push(rst);
  19. ops.push(sign);
  20. rst = ;
  21. sign = ;
  22. }
  23. if (c == ')' && ops.size()) {
  24. rst = ops.top() * rst + nums.top();
  25. ops.pop(); nums.pop();
  26. }
  27. }
  28. }
  29. rst += sign * num;
  30. return rst;
  31. }
  32. };

也可以参考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. 实体写到redis写不进去--误把类当成实体类

    之前一直都把实体写入redis都没有问题,今天再次这样干,结果却是怎么写都写不进去,redis里的值老是为空 最后才发现把类当成了实体类,当然写不进去了. 把类: /// <summary> ...

  2. LeetCode 397. Integer Replacement

    397. Integer Replacement QuestionEditorial Solution My Submissions   Total Accepted: 5878 Total Subm ...

  3. angularJS全选功能实现

    最近在做的一个项目要增加全选和反选功能,之前只做过JQ版的全选和反选. 实现效果: 1.点击全选checkbox可以切换全选和全部清空 2.点击列表中的checkbox,当全部选中时全选选中 3.在全 ...

  4. python中logging

    1.root logger以及logger斧子关系    http://www.pythonclub.org/modules/logging #coding=utf-8 __author__ = 'n ...

  5. (转载)afxres找不到问题

    在试用VS2010时一个问题困扰了我,就是打开c++项目后,rc的dialog进不去,没法拖控件,把我给抓狂的...而且网上大部分说的都是Directions的问题..我的问题明显不是这个问题. 于是 ...

  6. 一个简单的 MVVM 实现

    简介 一个简单的带有双向绑定的 MVVM 实现. 例子 使用 新建一个 ViewModel 对象, 参数分别为 DOM 元素以及绑定的数据即可. 指令 本 MVVM 的指令使用 data 数据, 即 ...

  7. C# 基础排序与查找算法

    排序算法: class Sort { static void swap<T>(ref T a, ref T b) { T tmp = a; a = b; b = tmp; } #regio ...

  8. Dev tdxDBTreeView

    可以快速的用tree展示层次结构,无需任何编码;对tree的操作会自动post到数据集:对数据集的操作会 在tree上表现 一.关键 设置 datasource displayField:节点的   ...

  9. sql server2008安装说明 详细完整版

    SQL Server 2008是一个重大的产品版本,它推出了许多新的特性和关键的改进,使得它成为至今为止的最强大和最全面的SQL Server版本. 在现今数据的世界里,公司要获得成功和不断发展,他们 ...

  10. js面向对象之创建对象

    工厂模式 function createPerson(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = ...