zoukankan      html  css  js  c++  java
  • 解题报告:LeetCode Basic Calculator(简单计算器)

    题目出处:https://leetcode.com/problems/basic-calculator/
    题意描述:
    给定一个只含加减号,括号,空格和非负数的合法字符串,在不调用库函数eval的条件下求出其值

    解决思路:
    由于此题只有加减号,因此不存在运算符优先级的问题,只需要稍微注意一下括号即可。
    因此,可以用两个栈ops,numbers来分别存储未处理的运算符和未处理的数字,并对字符串进行一次扫描。对于对于扫描到的任意字符是s[i],做如下处理:
      若s[i]为空格,则继续扫描。
      若s[i]为左括号‘(’,则直接进栈
      若s[i]为右括号‘)’,则将栈中左括号之上的所有运算符按照从上之下的顺序依次处理,处理完毕后将左括号出栈。
      若s[i]为加号‘+’或减号‘-’,则判定上一运算符是否是否存在,且是否是左括号‘(’,若存在且不是,则将numbers栈顶的俩数出栈,与运算符计算出结果将结果压入栈。否则直接将该运算符压入栈。
      若s[i]为数字则取出当前所在位置的所有数字并求出该值,将该数压入numbers栈,并将扫描指针往后移相应的位置。
    最后,扫描结束后,直接输出numbers栈顶的元素即可。

    算法复杂度分析:
      此算法对字符串进行了一次扫描,时间复杂度为O(n),用了两个栈来存储字符串中的内容,因此空间复杂度也为O(n),其中n为字符串的长度。

    下面直接附上源码(注:为了后续程序判断简洁,在函数calculate的开始进行了预处理,在运算符栈ops中压入了左括号‘(’,并在s末尾加入了右括号‘)’ )

     1 #include <iostream>
     2 #include <string>
     3 #include <ctype.h>
     4 #include <stack>
     5 using namespace std;
     6 
     7 class Solution {
     8 public:
     9 
    10     int op(int n1, int n2, char c)
    11     {
    12         int ans = 0;
    13         switch(c)
    14         {
    15             case '+': 
    16                 ans = n1+n2; 
    17                 break;
    18             case '-': 
    19                 ans = n1-n2; 
    20                 break;
    21         }
    22         return ans;
    23     }
    24 
    25     int calculate(string s) 
    26     {
    27         stack<char> ops;
    28         stack<int>     numbers;
    29         ops.push('(');
    30         s.push_back(')');
    31         for(int i = 0; i < s.length(); i ++)
    32         {
    33             switch(s[i])
    34             {
    35             case ' ': continue;          break;
    36             case '(': ops.push(s[i]);    break;
    37             case ')':
    38                 while(ops.top() != '(')
    39                 {
    40                     int n1 = numbers.top();
    41                        numbers.pop();
    42                        int n2 = numbers.top();
    43                        numbers.pop();
    44                     char op_top = ops.top();
    45                     ops.pop();
    46                     numbers.push(op(n2, n1, op_top));
    47                 }
    48                 ops.pop();
    49                 break;
    50             case '+':
    51             case '-':
    52                 if(ops.empty() || ops.top() != '(')
    53                 {
    54                     int n1 = numbers.top();
    55                        numbers.pop();
    56                        int n2 = numbers.top();
    57                        numbers.pop();
    58                     char op_top = ops.top();
    59                     ops.pop();
    60                     numbers.push(op(n2, n1, op_top));
    61                 }
    62                 ops.push(s[i]);
    63                 break;
    64             default:
    65                 int num = s[i]-'0';
    66                 while(isdigit(s[i+1]))
    67                 {
    68                     num = num*10+s[++i]-'0';
    69                 }
    70                 numbers.push(num);
    71                 break;
    72             }
    73         }
    74         return numbers.top();
    75     }
    76 };
    77 
    78 int main()
    79 {
    80     Solution solution;
    81     string s;
    82     cin >> s;
    83     cout << solution.calculate(s) << endl;
    84     
    85     return 0;
    86 }
    此博客中的内容均为原创或来自网络,不用做任何商业用途。欢迎与我交流学习,我的邮箱是b-liu14@mails.tsinghua.edu.cn
  • 相关阅读:
    第三届蓝桥杯CC++B组3
    第三届蓝桥杯CC++B组2
    第三届蓝桥杯CC++B组1
    第四届蓝桥杯c/c++B组3
    第四届蓝桥杯c/c++B组4
    第四届蓝桥杯c/c++B组5
    Nodejs RESTFul架构实践之api篇
    Request —— 让 Node.js http请求变得超简单
    [转]在SqlServer 中解析JSON数据
    JavaScript异步编程的Promise模式
  • 原文地址:https://www.cnblogs.com/bill-liu/p/4892969.html
Copyright © 2011-2022 走看看