s
,请你实现一个基本计算器来计算并返回它的值。 注意:不允许使用任何将字符串作为数学表达式计算的内置函数,比如 eval()
。
示例 1:
输入:s = "1 + 1"
输出:2
示例 2:
输入:s = " 2-1 + 2 "
输出:3
示例 3:
输入:s = "(1+(4+5+2)-3)+(6+8)"
输出:23
提示:
1 <= s.length <= 3 * 105
s
由数字、'+'
、'-'
、'('
、')'
、和' '
组成s
表示一个有效的表达式- '+' 不能用作一元运算(例如, "+1" 和
"+(2 + 3)"
无效) - '-' 可以用作一元运算(即 "-1" 和
"-(2 + 3)"
是有效的) - 输入中不存在两个连续的操作符
- 每个数字和运行的计算将适合于一个有符号的 32位 整数
bool isOperator(char c)
{
if (c == '+' || c == '-' || c == '*' || c == '/' || c == ' ' || c == '(' || c == ')')
return true;
return false;
}
int getNum(string &s, int start, int &end)
{
int cur = start;
bool isNegative = false;
if (cur < s.size() && s[cur] == '-')
{
isNegative = true;
cur++;
start = cur;
}
while (cur<s.size() && isOperator(s[cur]) == false)
{
if (s[cur] == ' ')
{
cur++;
continue;
}
cur++;
}
string tmp = s.substr(start, cur - start);
end = cur;
int a = std::stoi(tmp);
if (isNegative)
{
a *= -1;
}
return a;
}
void calNum(stack<int>&numStk, stack<char> &symbolStk)
{
char c = symbolStk.top();
symbolStk.pop();
int a = numStk.top();
numStk.pop();
int b = numStk.top();
numStk.pop();
switch (c)
{
case '+':
numStk.push(a + b);
break;
case '-':
numStk.push(b - a);
break;
case '*':
numStk.push(a*b);
break;
case '/':
numStk.push(b / a);
break;
default:
break;
}
}
bool isSameSymbol(stack<char> &symbolStk, char c)
{
if (c == '-' || c == '+')
{
if (symbolStk.size() > 0 && (symbolStk.top() == '-' || symbolStk.top() == '+'))
{
return true;
}
}
if (c == '/' || c == '*')
{
if (symbolStk.size() > 0 && (symbolStk.top() == '/' || symbolStk.top() == '*'))
{
return true;
}
}
return false;
}
//#include <string>
//#include <algorithm>
#include <cctype>
int calculate(string s) {
s.erase(std::remove_if(s.begin(), s.end(), [](char c) {return std::isspace(c);}), s.end());
stack<int>numStk;
stack<char> symbolStk;
int cur = 0;
while (cur<s.size())
{
bool isNum = false;
if (s[cur] == ' ')
{
cur++;
continue;
}
if (s[cur] == '-')
{
if (cur == 0 ||s[cur-1]=='(' ) //前面补充 0
{
numStk.push(0);
symbolStk.push('-');
cur++;
continue;
}
else if (cur - 1 >= 0 && s[cur-1]!=')' && isOperator(s[cur - 1]))
{
numStk.push(getNum(s, cur, cur));
isNum = true;
}
else
{
if (isSameSymbol(symbolStk, s[cur]))
{
calNum(numStk, symbolStk);
}
symbolStk.push('-');
cur++;
continue;
}
}
//符号
else if (isOperator(s[cur]))
{
if (s[cur] == ')')
{
//计算
while (symbolStk.top() != '(' && numStk.size()>=2)
{
calNum(numStk, symbolStk);
}
symbolStk.pop();//'('
cur++;
continue;
}
else
{
if (isSameSymbol(symbolStk, s[cur]))
{
calNum(numStk, symbolStk);
}
symbolStk.push(s[cur]);
cur++;
continue;
}
}
//数字
else
{
numStk.push(getNum(s, cur, cur));
isNum = true;
}
//处理 * /
if (isNum == true)
{
if (symbolStk.size()>0 && (symbolStk.top() == '*' || symbolStk.top() == '/'))
{
calNum(numStk, symbolStk);
}
}
}
if (symbolStk.size()>0 && numStk.size()>=2)
{
calNum(numStk, symbolStk);
}
//最后一个是负数
if (symbolStk.size()>0 && symbolStk.top() == '-')
{
return numStk.top()* -1;
}
return numStk.top();
}