Leetcode 227 BasicCalculatorII(C++ Solution)
基本计算器 中缀表达式 转化为 后缀表达式
问题描述
给你一个字符串表达式 s
,请你实现一个基本计算器来计算并返回它的值。
整数除法仅保留整数部分。
样例
输入:s = "3+2*2"
输出:7
输入:s = " 3/2 "
输出:1
输入:s = " 3+5 / 2 "
输出:5
提示
1 <= s.length <= 3 * 105
s 由整数和算符 ('+', '-', '*', '/') 组成,中间由一些空格隔开
s 表示一个 有效表达式
表达式中的所有整数都是非负整数,且在范围 [0, 231 - 1] 内
题目数据保证答案是一个 32-bit 整数
思路(Algorithm)
中缀表达式转为后缀表达式
数据结构:
- stack<char> note // 记录过程中的字符
- vector<string> tokens // 保存生成的后缀表达式
- map<char,int> priority // 定义当前操作符号的优先级,用户可以自己调整
算法:
1、线性扫描一个表达式,当当前字符为:
1)数字
继续向后扫描,直到当前符号不是数字,将得到的完整操作数push入tokens
e.g input="321+321"时,扫描到第一个字符“3”时,应取完整的操作数“321”
2)’(’
将’('压入note中,继续向下扫描
3)’)’
① 将note栈顶的元素弹出,直至栈为空或栈顶元素为’(’;
② 再将’('弹出
4)操作符
① 将note栈顶的元素弹出,当 栈非空 且 栈顶元素非’(’ 且 栈顶元素的优先级大于等于当前元素的优先级 时 (优先级高的符号先进行计算)
② 将当前符号压入note
2、最后将note栈中所有的元素弹出,并将其push到tokens中
实现代码(Implement)
#include<string>
#include<vector>
#include<stack>
#include<algorithm>
#include<map>
using namespace std;
class Solution {
private:
map<char, int> priority;
vector<string> toReversePolishNotion(string s) {
vector<string> tokens;
stack<char> note;
tokens.push_back("0"); // 避免-1+2
int i = 0,n=s.length();
while(i<n){
switch (s[i]) {
case ' ':
break;
case '(':
note.push(s[i]);
break;
case ')':
while (!note.empty() && note.top() != '(') {
tokens.push_back(string(1, note.top()));
note.pop();
}
note.pop();
break;
case '+':
case '-':
case '*':
case '/':
while (!note.empty() && note.top() != '('&&priority[note.top()]>=priority[s[i]]) {
tokens.push_back(string(1, note.top()));
note.pop();
}
note.push(s[i]);
break;
default:
string str = "";
while (i<n&&isdigit(s[i])) {
str += s[i];
i++;
}
tokens.push_back(str);
i--;
break;
}
i++;
}
while (!note.empty()) {
tokens.push_back(string(1,note.top()));
note.pop();
}
return tokens;
}
int calNPR(vector<string> express) {
stack<int> result;
for (string element : express) {
if (element=="+"|| element == "-" || element == "*" || element == "/") {
int re = result.top();
result.pop();
int le = result.top();
result.pop();
switch (element[0]) {
case '+':
result.push(le + re);
break;
case '-':
result.push(le - re);
break;
case '*':
result.push(le * re);
break;
case '/':
result.push(le / re);
break;
}
}
else {
result.push(stoi(element));
}
}
return result.top();
}
public:
int calculate(string s) {
priority['*'] = 1;
priority['/'] = 1;
priority['+'] = 0;
priority['-'] = 0;
vector<string> tokens = toReversePolishNotion(s);
return calNPR(tokens);
}
};
复杂度分析
时间复杂度:
O( n n n)
空间复杂度:
O( n n n)
声明
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/basic-calculator-ii/
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
参考文章
私以为讲解的很好,图文并用,生动形象