在C ++中从string评估算术expression式

我正在寻找一种简单的方法来评估一个简单的mathexpression式,如下所示:

3 * 2 + 4 * 1 +(4 + 9)* 6

我只想要+*操作加()标志。 *优先于+

我想你正在寻找一个简单的recursion下降parsing器 。

这是一个非常简单的例子:

 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; } 

你可以试试: http : //partow.net/programming/exprtk/index.html

  1. 很简单
  2. 只需要包含“exprtk.hpp”到您的源代码。
  3. 你可以dynamic地改变expression式的variables值。
  4. 好的起点: http : //partow.net/programming/exprtk/code/exprtk_simple_example_01.cpp

只是添加另一种select,考虑尝试TinyExpr这个问题。 它是开源的,并且包含在一个源代码文件中。 它实际上是用C语言编写的,但是按照我的经验,它会像C ++一样干净地编译。

从上面解决您的示例expression式就像下面这样简单:

 #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; } 

在search一个类似的任务库时,我发现了libmatheval 。 似乎是一个正确的事情。 不幸的是,GPL,这是我无法接受的。

 import java.util.Deque; import java.util.LinkedList; public class EvaluateArithmeticExpression { public static void main(String[] args) { System.out.println(evaluate("-4*2/2^3+3")==-4*2/Math.pow(2, 3)+3); System.out.println(evaluate("12*1314/(1*4)+300")==12*1314/(1*4)+300); System.out.println(evaluate("123-(14*4)/4+300")==123-(14*4)/4+300); System.out.println(evaluate("12*4+300")==12*4+300); } public static int evaluate(String s){ Deque<Integer> vStack= new LinkedList<>(); Deque<Character> opStack= new LinkedList<>(); int i=0; while(i<s.length()){ if(isNum(s,i) ) i=getNum(s,vStack,i); else if(isOp(s,i)) i=doOp(s,opStack,vStack,i); } doOp(opStack,vStack); return vStack.pop(); } private static int getNum(String s, Deque<Integer> vStack,int i){ int sign=1; if(s.charAt(i)=='-' || s.charAt(i)=='+') sign=s.charAt(i++)=='-'?-1:1; int val=0; while(i<s.length() && isNum(s,i)) val=val*10+s.charAt(i++)-'0'; vStack.push(sign*val); return i; } private static int doOp(String s, Deque<Character> opStack,Deque<Integer> vStack,int i){ char op=s.charAt(i); if(op=='(') opStack.push(op); else{ if(op==')'){ while(!opStack.isEmpty() && opStack.peekFirst()!='(') doOp(opStack,vStack); opStack.pop(); } else{ while(!opStack.isEmpty() && prior(op)<=prior(opStack.peekFirst())) doOp(opStack,vStack); opStack.push(op); } } return i+1; } private static int prior(char op){ switch(op){ case '+': case '-': return 1; case '*': case '/': return 2; case '^': return 4; } return 0; } private static void doOp(Deque<Character> opStack,Deque<Integer> vStack){ int b=vStack.isEmpty()?0:vStack.pop(); int a=vStack.isEmpty()?0:vStack.pop(); char op=opStack.pop(); int res=evaluate(a,b,op); vStack.push(res); } private static int evaluate(int a, int b, char op){ switch(op){ case '+': return a+b; case '-': return ab; case '/': return a/b; case '*': return a*b; case '^': return (int)Math.pow(a,b); } return 0; } private static boolean isNum(String s, int i){ return '0'<=s.charAt(i) && s.charAt(i)<='9'; } private static boolean isOp(String s, int i){ return "()+-*/^".contains(String.valueOf(s.charAt(i))); } } 

我在C#中编写了一个非常简单的expression式求值器(为了使其符合C ++标准,需要进行最小的修改)。 它是基于expression式树的构build方法,只有树没有实际构build,而是所有节点都在原地进行了评估。

你可以在这个地址find它: 简单的算术expression式计算器

我想你可以在这篇文章中find答案: 评估string“3 *(4 + 2)”yield int 18

或者你可以试试这个库: http : //weblogs.asp.net/pwelter34/archive/2007/05/05/calculator-net-calculator-that-evaluates-math-expressions.aspx

这里有一个关于复杂(不是真正的:p)mathexpression式的评估树的一个很好的小介绍:

~cs1044/spring01/cstruble/notes/6.complexexpr.pdf

它会引导你通过它的风格;)