从 C++ 中的字符串计算算术表达式
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9329406/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Evaluating arithmetic expressions from string in C++
提问by Mahdi Ghiasi
I'm searching for a simple way to evaluate a simple math expression from an string, like this:
我正在寻找一种简单的方法来计算字符串中的简单数学表达式,如下所示:
3*2+4*1+(4+9)*6
3*2+4*1+(4+9)*6
I just want +
and *
operations plus (
and )
signs. And *
has more priority than +
.
我只想要+
和*
操作加号(
和)
标志。并且*
比 具有更多的优先级+
。
采纳答案by Henrik
I think you're looking for a simple recursive descent parser.
我认为您正在寻找一个简单的递归下降解析器。
Here's a very simple example:
这是一个非常简单的例子:
const char * expressionToParse = "3*2+4*1+(4+9)*6";
char peek()
{
return *expressionToParse;
}
char get()
{
return *expressionToParse++;
}
int expression();
int number()
{
int result = get() - '0';
while (peek() >= '0' && peek() <= '9')
{
result = 10*result + get() - '0';
}
return result;
}
int factor()
{
if (peek() >= '0' && peek() <= '9')
return number();
else if (peek() == '(')
{
get(); // '('
int result = expression();
get(); // ')'
return result;
}
else if (peek() == '-')
{
get();
return -factor();
}
return 0; // error
}
int term()
{
int result = factor();
while (peek() == '*' || peek() == '/')
if (get() == '*')
result *= factor();
else
result /= factor();
return result;
}
int expression()
{
int result = term();
while (peek() == '+' || peek() == '-')
if (get() == '+')
result += term();
else
result -= term();
return result;
}
int _tmain(int argc, _TCHAR* argv[])
{
int result = expression();
return 0;
}
回答by Monir
One can try : http://partow.net/programming/exprtk/index.html
可以试试:http: //partow.net/programming/exprtk/index.html
- very simple
- only need to include "exprtk.hpp" to your source code.
- you can change the value of variables of the expression dynamically.
- good starting point: http://partow.net/programming/exprtk/code/exprtk_simple_example_01.cpp
- 很简单
- 只需要在您的源代码中包含“exprtk.hpp”。
- 您可以动态更改表达式的变量值。
- 好的起点:http: //partow.net/programming/exprtk/code/exprtk_simple_example_01.cpp
回答by IsaacH
Just to add another alternative, consider trying TinyExprfor this problem. It's open source and self-contained in one source code file. It is actually written in C, but it will compile cleanly as C++ in my experience.
只是为了添加另一种选择,考虑尝试使用TinyExpr来解决这个问题。它是开源的并且自包含在一个源代码文件中。它实际上是用 C 编写的,但根据我的经验,它可以像 C++ 一样干净地编译。
Solving your example expression from above is as simple as:
从上面解决您的示例表达式非常简单:
#include "tinyexpr.h"
#include <stdio.h>
int main()
{
double answer = te_interp("3*2+4*1+(4+9)*6", 0);
printf("Answer is %f\n", answer);
return 0;
}
回答by Yury
While searching a library for a similar task I found libmatheval. Seems to be a proper thing. Unfortunately, GPL, which is unacceptable for me.
在为类似任务搜索库时,我找到了libmatheval。似乎是理所应当的事情。不幸的是,GPL,这对我来说是不可接受的。
回答by Mustafa Y?ld?z
So I was searching an answer for this question. And I was trying to create my own programming language. For math expressions I was in need of that function.
所以我正在寻找这个问题的答案。我试图创建自己的编程语言。对于数学表达式,我需要该函数。
Oke give I'll give it to you. Use it the way you want.
好的,给我给你。以您想要的方式使用它。
/* Code here before is useless now */
This is kind a long and probably an unefficient way of doing such a task. But it gets job done so go for it. Soon I'm planning on adding variable support. But you can do it too, it's pretty easy (I suppose :P).
这是完成此类任务的一种漫长且可能效率低下的方式。但它完成了工作,所以去吧。很快我计划添加变量支持。但是你也可以做到,这很容易(我想:P)。
EDIT: I just tidied up the function now it works like magic XD..
编辑:我刚刚整理了这个功能,现在它像魔术一样工作 XD ..
using namespace std;
double eval(string expr)
{
string xxx; // Get Rid of Spaces
for (int i = 0; i < expr.length(); i++)
{
if (expr[i] != ' ')
{
xxx += expr[i];
}
}
string tok = ""; // Do parantheses first
for (int i = 0; i < xxx.length(); i++)
{
if (xxx[i] == '(')
{
int iter = 1;
string token;
i++;
while (true)
{
if (xxx[i] == '(')
{
iter++;
} else if (xxx[i] == ')')
{
iter--;
if (iter == 0)
{
i++;
break;
}
}
token += xxx[i];
i++;
}
//cout << "(" << token << ")" << " == " << to_string(eval(token)) << endl;
tok += to_string(eval(token));
}
tok += xxx[i];
}
for (int i = 0; i < tok.length(); i++)
{
if (tok[i] == '+')
{
//cout << tok.substr(0, i) + " + " + tok.substr(i+1, tok.length()-i-1) << " == " << eval(tok.substr(0, i)) + eval(tok.substr(i+1, tok.length()-i-1)) << endl;
return eval(tok.substr(0, i)) + eval(tok.substr(i+1, tok.length()-i-1));
} else if (tok[i] == '-')
{
//cout << tok.substr(0, i) + " - " + tok.substr(i+1, tok.length()-i-1) << " == " << eval(tok.substr(0, i)) - eval(tok.substr(i+1, tok.length()-i-1)) << endl;
return eval(tok.substr(0, i)) - eval(tok.substr(i+1, tok.length()-i-1));
}
}
for (int i = 0; i < tok.length(); i++)
{
if (tok[i] == '*')
{
//cout << tok.substr(0, i) + " * " + tok.substr(i+1, tok.length()-i-1) << " == " << eval(tok.substr(0, i)) * eval(tok.substr(i+1, tok.length()-i-1)) << endl;
return eval(tok.substr(0, i)) * eval(tok.substr(i+1, tok.length()-i-1));
} else if (tok[i] == '/')
{
//cout << tok.substr(0, i) + " / " + tok.substr(i+1, tok.length()-i-1) << " == " << eval(tok.substr(0, i)) / eval(tok.substr(i+1, tok.length()-i-1)) << endl;
return eval(tok.substr(0, i)) / eval(tok.substr(i+1, tok.length()-i-1));
}
}
//cout << stod(tok.c_str()) << endl;
return stod(tok.c_str()); // Return the value...
}
回答by Zoran Horvat
I've written a very simple expression evaluator in C# (minimal changes required to make it C++-compliant). It is based on expression tree building method, only that tree is not actually built but all nodes are evaluated in-place.
我已经用 C# 编写了一个非常简单的表达式计算器(使其符合 C++ 所需的最小更改)。它基于表达式树构建方法,只是实际上并未构建该树,而是就地评估所有节点。
You can find it on this address: Simple Arithmetic Expression Evaluator
你可以在这个地址上找到它:Simple Arithmetic Expression Evaluator