2011-04-22 11 views
4

数式を解析できるプログラムを作成する必要があります。数式と数式パーサーアルゴリズム

入力:5X + 7^SIN(Z)/ 2T + 44
出力:X、Z、Tの値を入力
入力:2、1、2
なお、以下、この例のように動作するはず出力:答えは:何かが


それがサポートしている必要があり(+、*、 - 、^、%、SIN、COS)
私は操車場アルゴリズムについてthisページを読みました

また、私はインフィクス式を後置または接頭辞に変換する方法も知っています。
それは私のアルゴリズムです:

1 - 式を与えます。
2 - (SIN、 COS)
4から離れて、すべての変数を探す - - 括弧はバランス1
3に進みます3 他のショーのエラーに進みますしている場合は 入力
5から変数を与える - 変数
6を交換してください - プレフィックス表現し、それを
7を計算する - 出力 と密接なプログラム

での表示結果がその権利ですか?私はCでそれを実装したい#
私のために役立つかもしれない任意のメモをお勧めします。

+0

、この[Q&A]を参照してください(http://stackoverflow.com/questions/4396080/antlr-3-3-c-tutorials)。 –

+1

[可能な数式を評価するための最善のアルゴリズム?](http://stackoverflow.com/questions/572796/best-algorithm-for-evaluating-a-mathematical-expression)の複製が可能です。 –

答えて

1

この(私はC#でこれを実行する方法を知りませんが、あなたはPythonの式として、あなたの表現を与える場合のpythonは、ここであなたを助けることができる非常に強力な構文木・アナライザ(ASTモジュール)を持っていますそれほど難しくないので、 '*'の乗算記号を追加するだけです:-))。

まず、(数が満たされたときに、visit_Numここで我々は唯一の識別子をしたい、などと呼ばれる別の1 visit_Exprを表現するために呼ばれ、たとえば、識別子のために呼ばれる)のみvisit_Nameメソッドを再定義の良いクラスを定義します。

>>> def visit(expression): 
    node = ast.parse(expression) 
    v = MyVisitor() 
    v.visit(node) 
    print v.identifiers 

それはOKになります:ASTため

>>> visit('x + 4 * sin(t)') 
['x', 't'] 
>>> visit('5*x + 7^sin(z)/2*T + 44') 
['x', 'z', 'T'] 

使用のpython 2.6または2.7

>>> import ast 
>>> class MyVisitor(ast.NodeVisitor): 
    def __init__(self, *args, **kwargs): 
     super(MyVisitor, self).__init__(*args, **kwargs) 
     self.identifiers = [] 

    def generic_visit(self, node): 
     ast.NodeVisitor.generic_visit(self, node) 

    def visit_Name(self, node): 
     # You can specify othe exceptions here than cos or sin 
     if node.id not in ['cos', 'sin']: 
      self.identifiers.append(node.id) 

は、その識別子あなたを与えるために式を取り、迅速関数を定義しますモジュール。

2

あなたは、SCRからこれを書くことにした場合atch、あなたのアルゴリズムはよさそうだ。私は私の思考のいくつかを提供します。

手順5(変数を置き換える)を手順6(式の前に接頭辞を付けて計算)に移動することができます。言い換えれば、変数のテキストの検索と置換を行うのではなく、変数を評価する必要があるときは常に計算中に行います。これにより、関数をグラフ化することや、他の変数に依存する値を持つ変数を簡単に作成できるようになる可能性があります。あなたの方法は単純なケースのために働くはずです。それが簡単に将来的に追加の関数を定義すること

sincos機能のための可能な実装、Dictionary<string, Func<double,double>>を持つことができ、のようなもの:あなたはANTLRを使用することができ

private var functions = 
    new Dictionary<string, Func<double,double>>(StringComparer.OrdinalIgnoreCase) 
    { 
     { "sin", Math.Sin }, 
     { "cos", Math.Cos }, 
     { "sec", Secant } 
    }; 

. . . 

// checking whether a token is a defined function or a variable 
if (functions.ContainsKey(token)) 
{ 
    // determine the value of the argument to the function 
    double inputValue = getArgument(); 
    double result = functions[token](inputValue); 
    . . . 
} 

. . . 

private static double Secant(double x) 
{ 
    return 1.0/Math.Cos(x); 
}