在C++中从字符串计算算术表达式
Evaluating arithmetic expressions from string in C++
我正在寻找一种从字符串中计算简单数学表达式的简单方法,如下所示:
3*2+4*1+(4+9)*6
我只想要+
和*
运算加上(
和)
符号。并且CCD_ 5比CCD_ 6具有更高的优先级。
您可以尝试:http://partow.net/programming/exprtk/index.html
- 非常简单
- 只需要在源代码中包含"exprtk.hpp"即可
- 您可以动态更改表达式中变量的值
- 良好的起点:http://partow.net/programming/exprtk/code/exprtk_simple_example_01.cpp
我认为您正在寻找一个简单的递归下降语法分析器。
这里有一个非常简单的例子:
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;
}
为了添加另一种选择,可以考虑尝试TinyExpr来解决这个问题。它是开源的,并且包含在一个源代码文件中。它实际上是用C编写的,但根据我的经验,它会干净地编译为C++。
从上面解决你的示例表达式很简单:
#include "tinyexpr.h"
#include <stdio.h>
int main()
{
double answer = te_interp("3*2+4*1+(4+9)*6", 0);
printf("Answer is %fn", answer);
return 0;
}
所以我在寻找这个问题的答案。我试图创建自己的编程语言。对于数学表达式,我需要那个函数。
好的,我会给你的。按照你想要的方式使用它。
/* Code here before is useless now */
这是一种很长的、可能效率很低的方式来完成这样的任务。但它完成了任务,所以去做吧。很快我就计划添加可变支持。但你也可以做,这很容易(我想:P)。
编辑:我刚刚整理了功能,现在它像魔术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...
}
在库中搜索类似任务时,我发现了libmatheval。这似乎是一件恰当的事情。不幸的是,GPL,这对我来说是不可接受的。
我用C#编写了一个非常简单的表达式计算器(使其符合C++所需的最小更改)。它是基于表达式树的构建方法,只是该树并没有实际构建,而是对所有节点进行了评估。
您可以在以下地址找到它:简单算术表达式计算器
将中缀表达式转换为后缀表达式。然后进行评估。
Postfix可能看起来像3 2 * 4 1 * + 4 9 + 6 * +
使用stack进行评估非常容易。
相关文章:
- (C++)分析树以计算返回错误值的简单算术表达式
- 断言中的Fold表达式在某些计算机上编译,但在其他计算机上不编译
- 如何计算具有指定类型的表达式的相对精度和绝对精度
- 编译器是否强制根据模板参数计算表达式?
- 为什么'typeid(x) == typeid(y)'的计算结果为 true,其中 'x' 和 'y' 分别是 T 和 T& 类型的 id-表达式?
- 如何在常量计算表达式中获取编译时错误?
- 计算阶乘的 C++17 倍表达式中的错误
- 计算表达式字符串由 std::map 中的键组成
- 复合赋值的左侧表达式是未初始化的值.计算出的值也将是垃圾
- 使用正则表达式C++计算数字中的十进制空格
- 是否可以定义以后可以计算的布尔表达式
- 如何使用 ASCII 转换使用字符堆栈计算后缀表达式
- std::d eclval 和未计算的表达式
- (类型)(数学表达式)是否计算此类型的表达式?
- 使用不同的表达式计算同一整数时的结果不一致
- 手动将二进制表达式计算为十六进制
- 使用链表在C++进行表达式计算
- 表示表达式计算c++(多态性设计)
- 此表达式计算什么
- 将空表达式计算为NOP