题目
- 请写一个整数计算器,支持加减乘三种运算和括号。
- 示例1
输入:“1+2”
返回值:3 - 示例2
输入:“(2*(3-4))*5”
返回值:-10 - 示例3
输入:“3+2*3*4-1”
返回值:26
思路
- 经典的中缀表达式求值。常用思路,将其转为后缀表达式(后缀表达式的特点:遇到运算符则将前两个数拿出来运算,便于计算机计算),边转边求值。
- 读到左括号 ( 较为特殊,读到左括号时直接入栈,
- 本题中运算符优先级:左括号或栈顶为空、乘、加减 、右括号。
- 读到右括号时一直出栈直到一个左括号出栈。
算法步骤
- 遍历字符串,当 遍历到的字符是数字 时,直接将其压入数字栈。
- 否则,当 遍历到的字符是运算符 时,判断字符,直到字符串读完:
- 若符号栈为空,则直接将其压入符号栈。
- 若符号栈非空,则判断符号栈栈顶的运算符优先级:
- 若 遍历到的运算符符号的优先级 > 符号栈栈顶元素的优先级,或符号栈空,则将读取的运算符压入符号栈。
- 若 遍历到的运算符符号的优先级 ≤ 符号栈栈顶元素的优先级,则将其出栈,并从数字栈弹出两个元素进行该运算,先弹出的为右操作数,后弹出的为左操作数,将结果压入数字栈。
- 最后,若符号栈非空,则弹出栈顶元素,并从数字栈弹出两个元素来进行该运算,重复该操作直到符号栈空。
- 符号栈为空后,弹出数字栈栈顶元素作为结果。
- 返回数值站栈顶元素作为最终结果。
int solve(string s) {
stack<char> sign;
stack<int> num;
for (int i = 0; i < s.length(); i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
int rear = i;
while ((rear + 1) < s.length() && s[rear + 1] >= '0' && s[rear + 1] <= '9')
{
rear++;
}
int n = 0;
for (int j = rear; j >= i; j--) {
n += (s[j] - '0') * pow(10, (rear - j));
}
i = rear;
num.push(n);
}
else if (s[i] == '(' || s[i] == '*'|| sign.size() == 0 )
{
sign.push(s[i]);
}
else if (s[i] == '+' || s[i] == '-')
{
while (1)
{
if (sign.size() == 0)
break;
if (sign.top() == '*')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 * n2);
}
else if (sign.top() == '+')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 + n2);
}
else if (sign.top() == '-')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 - n2);
}
else {
break;
}
}
sign.push(s[i]);
}
else if (s[i] == ')')
{
while (1)
{
if (sign.size() == 0)
{
break;
}
else if (sign.top() == '(')
{
sign.pop();
break;
}
else if (sign.top() == '+')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 + n2);
}
else if (sign.top() == '-')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 - n2);
}
else if (sign.top() == '*')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 * n2);
}
}
}
}
while (sign.size() != 0)
{
if (sign.top() == '+')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 + n2);
}
else if (sign.top() == '-')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 - n2);
}
else if (sign.top() == '*')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 * n2);
}
}
return num.top();
}
实例
#include <iostream>
#include <stack>
using namespace std;
int solve(string s) {
stack<char> sign;
stack<int> num;
for (int i = 0; i < s.length(); i++)
{
if (s[i] >= '0' && s[i] <= '9')
{
int rear = i;
while ((rear + 1) < s.length() && s[rear + 1] >= '0' && s[rear + 1] <= '9')
{
rear++;
}
int n = 0;
for (int j = rear; j >= i; j--) {
n += (s[j] - '0') * pow(10, (rear - j));
}
i = rear;
num.push(n);
}
else if (s[i] == '(' || s[i] == '*'|| sign.size() == 0 )
{
sign.push(s[i]);
}
else if (s[i] == '+' || s[i] == '-')
{
while (1)
{
if (sign.size() == 0)
break;
if (sign.top() == '*')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 * n2);
}
else if (sign.top() == '+')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 + n2);
}
else if (sign.top() == '-')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 - n2);
}
else {
break;
}
}
sign.push(s[i]);
}
else if (s[i] == ')')
{
while (1)
{
if (sign.size() == 0)
{
break;
}
else if (sign.top() == '(')
{
sign.pop();
break;
}
else if (sign.top() == '+')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 + n2);
}
else if (sign.top() == '-')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 - n2);
}
else if (sign.top() == '*')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 * n2);
}
}
}
}
while (sign.size() != 0)
{
if (sign.top() == '+')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 + n2);
}
else if (sign.top() == '-')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 - n2);
}
else if (sign.top() == '*')
{
sign.pop();
int n2 = num.top();
num.pop();
int n1 = num.top();
num.pop();
num.push(n1 * n2);
}
}
return num.top();
}
int main()
{
string mys = "1+3*(5+2)";
cout<< mys<<"=" << solve(mys) << endl;
return 0;
}