18 | C++表达式计算
最初想要在 C++ 中找到 类似 python 中 eval
的实现,但是找了好久都没有找到,即 将字符串转换成表达式进行求值 的愿望终究还是没有实现。但是如果字符串是简单的 算术表达式的话,还是可以做的。
下面就来分享大佬的代码,已经忘记在哪里找到的了。
// CPP program to evaluate a given
// expression where tokens are
// separated by space.
#include <bits/stdc++.h>
using namespace std;
// 1.返回运算符 + - * / 的优先级
int precedence(char op){
if(op == '+'||op == '-')
return 1;
if(op == '*'||op == '/')
return 2;
return 0;
}
// 2.得到操作符的运算结果
int applyOp(int a, int b, char op){
switch(op){
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
}
// Function that returns value of
// expression after evaluation.
int evaluate(string tokens){
int i;
// stack to store integer values.
stack <int> values;
// stack to store operators.
stack <char> ops;
for(i = 0; i < tokens.length(); i++){
// Current token is a whitespace,
// skip it.
if(tokens[i] == ' ')
continue;
// Current token is an opening
// brace, push it to 'ops'
else if(tokens[i] == '('){
ops.push(tokens[i]);
}
// Current token is a number, push
// it to stack for numbers.
else if(isdigit(tokens[i])){
int val = 0;
// There may be more than one
// digits in number.
while(i < tokens.length() &&
isdigit(tokens[i]))
{
val = (val*10) + (tokens[i]-'0');
i++;
}
values.push(val);
// right now the i points to
// the character next to the digit,
// since the for loop also increases
// the i, we would skip one
// token position; we need to
// decrease the value of i by 1 to
// correct the offset.
i--;
}
// Closing brace encountered, solve
// entire brace.
else if(tokens[i] == ')')
{
while(!ops.empty() && ops.top() != '(')
{
int val2 = values.top();
values.pop();
int val1 = values.top();
values.pop();
char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
// pop opening brace.
if(!ops.empty())
ops.pop();
}
// Current token is an operator.
else
{
// While top of 'ops' has same or greater
// precedence to current token, which
// is an operator. Apply operator on top
// of 'ops' to top two elements in values stack.
while(!ops.empty() && precedence(ops.top())
>= precedence(tokens[i])){
int val2 = values.top();
values.pop();
int val1 = values.top();
values.pop();
char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
// Push current token to 'ops'.
ops.push(tokens[i]);
}
}
// Entire expression has been parsed at this
// point, apply remaining ops to remaining
// values.
while(!ops.empty()){
int val2 = values.top();
values.pop();
int val1 = values.top();
values.pop();
char op = ops.top();
ops.pop();
values.push(applyOp(val1, val2, op));
}
// Top of 'values' contains result, return it.
return values.top();
}
int main() {
cout << evaluate("10 + 2 * 6") << "\n";
cout << evaluate("100*2+12") << "\n";
cout << evaluate("100 * ( 2 + 12 )") << "\n";
cout << evaluate("100*(2+12)/14");
system("pause");
return 0;
}
// This code is contributed by Nikhil jindal.