1

式ツリーを構築しようとすると頭痛があります。具体的には、実装する方法や実際にデータを格納するノードを作成する手がかりがないtreenodesのポインタです。かなり基本的ですが、コードが私を混乱させます。例えば式ツリーの実装の問題

、私はこれはそれがどのように見えるかである5 + 5の発現作成する:これを実装するときに、私が開始するかどうかはわかりませんが

+ 
/\ 
5 5 

を。どのようにしてルートノードの演算子と子ノードの番号を取得するのですか?私はそれらをスタックに格納してトップを読むことができますが、セットの親、左の子および右の子のメソッドは(TreeNode *)引数を取るだけですが、ベクトルトークンは型の文字列です。

また、TreeNodeのコンストラクタは整数と演算子の値をとりますが、それはなぜですか?これらの値をルート、親、子としてそれぞれのノードにどうやって取得できますか?

ExprTree.cpp 

    #include "ExprTree.h" 
    #include <sstream> 
    #include <iostream> 

    TreeNode * createOperatorNode(const string & op){ 

     if (op == "+") return new TreeNode(Plus); 
     if (op == "-") return new TreeNode(Minus); 
     if (op == "*") return new TreeNode(Times); 
     if (op == "/") return new TreeNode(Divide); 
     return new TreeNode(NoOp); 

    } 

    /* 
    * Basic constructor that sets up an empty Expr Tree. 
    */ 
    ExprTree::ExprTree(){ 

     this->root = NULL; 
     this-> _size = 0; 

    } 

    /* 
    * Constructor that takes a TreeNode and sets up an ExprTree with that node at the root. 
    */ 
    ExprTree::ExprTree(TreeNode * r){ 

     this->root = r; 
    } 

    ExprTree ExprTree::buildTree(vector<string> tokens){ 

// the tokens are the broken up arithimec expression 
i.e 
5 
+ 
5 
// not sure what to do here, i've tried using stacks but i wasn't sure how to get the stored data into the nodes. 

    } 

TreeNode.cpp

#include "TreeNode.h" 

TreeNode::TreeNode(Operator o){ 
    op = o; 
    parent = 0; 
    leftChild = 0; 
    rightChild = 0; 
} 

TreeNode::TreeNode(int val){ 
    op = Value; 
    value = val; 
    parent = 0; 
    leftChild = 0; 
    rightChild = 0; 
} 

TreeNode.h

#include <string> 
#include <sstream> 

enum Operator {Value, Plus, Minus, Times, Divide, NoOp}; 

class TreeNode { 

private: 

    Operator op; //If this node represents an operator, this is where it's stored. 
       //It can take values from the Operator enum (i.e. Plus, Minus, etc.) 
       //If it represents a value, use the Value value. :D 
    int value; //If this node stores an actual number, this is it. 

    TreeNode * parent; //Pointer to the parent. 
    TreeNode * leftChild; //Pointer to the left child of this node. 
    TreeNode * rightChild; //Pointer to the right child of this node. 

public: 

    TreeNode(Operator); //Constructor to use for +, -, * and /. 
         //Example: TreeNode(Plus); 
    TreeNode(int); //Constructor to use for actual numbers. 
       //Example: TreeNode(5); 
    void setParent(TreeNode *); //Set the parent pointer. 
    void setLeftChild(TreeNode *); //Set the left child pointer. 
    void setRightChild(TreeNode *); //Set the right child pointer. 
    TreeNode * getParent(); //Get the parent pointer. 
    TreeNode * getLeftChild(); //Get the left child pointer. 
    TreeNode * getRightChild(); //Get the right child pointer. 
    int getValue(); //Returns the stored value; 
    Operator getOperator(); //Returns the stored operator. 
    bool isValue(); //Returns true if this node is a Value node. 
    bool isOperator(); //Returns truee if this node is Plus, Minus, Times or Divide node. 
    std::string toString(); //Returns a simple string representation of the node. 

}; 
+0

「ExprTree.h」はどこですか? –

答えて

0

式を解析する最も簡単な方法は、再帰下降パーサを構築することです。これは、式、項、および因子と呼ばれる相互に再帰的な関数で構成されます。因数は最小の単位で、基本数か開いたかっこ、式、閉じ括弧のいずれかです(相互の再帰が入ります)。用語は、乗算および除算演算子の要素の集合であり、式は、プラスおよびマイナス演算子によって結合された用語の集合です。

単項マイナスの特別なルールが必要です。

ここで、再帰的降下パーサーは実際にメモリ内の構造としてツリーを構築しません。ツリーは呼び出しパターンに暗黙的に含まれています。しかし、ツリーが必要ならば、それを簡単に変更してツリーを構築することができます。

それは私の非常にシンプルな基本的な通訳あなたは単にTreeNode.hはあなたを与えるものを使用

https://github.com/MalcolmMcLean/minibasic

0

を見てみるために役立つかもしれません。例えば

あなたは5 + 5を表す名前のルートでツリーを作成したい場合、あなたはパーサ内

TreeNode root(Plus); 
root.setLeftChild(new TreeNode(5)); 
root.setRightChild(new TreeNode(5)); 

のように行って、よく、ものを構築してみてください。子供と親ポインタをたどることで、ツリーを簡単にたどることができます。

もう一つの方法は、最も外側の演算子として評価し、再帰的にそれは発言のように、言った

TreeNode::TreeNode(string expression){ 

    if(expression is number){ 
     create this as number node 
    } 
    create this as operator node with outermost operator 
    split string by outermost operator 
    set left child to left side of split string 
    set right child to ... 
} 

のように、彼らに適切な部分文字列を与えることで、子どもたちの構築文字列、以上のコンストラクタを作成することです、 ~TreeNode()が定義されていません。つまり、メモリリークが発生します。

また、ツリーとツリーノードを分離することをお勧めします。つまり、内部クラスとしてTreeNodeを持つクラスツリーを作成し、TreeNodeのコンストラクタとデストラクタはプライベート(ツリーはフレンド)です。物事をよりコントロールすることができます。 setLeftChildなどのアクションは、誤って実行された場合にメモリリークが発生すると危険です(ツリーのアイデアを無視するループを作成することができます)。

0

まず、式を後置式(Infix To Postfix)に変換します。

式:5 + 5

のPostfix:5 5 +

は、次に接尾文字列を解析し、いつでもあなたは、オペランドスタックに押し込み見つけるか、オペレータを見つけた場合、2つのオペランドをポップスタックから(バイナリ演算子の場合)、ツリールートを演算子として左の&の子をオペランドとして割り当てます。

Tree *t; 
Stack<string> stack; 

// parsing the tokens(expression)... 
for(int i=0; i<token[i].length(); i++) { 
    if(token[i] == "+" || token[i] == "-" || token[i] == "*" || token[i] == "/") { 
     string op1 = stack.top(); stack.pop(); 
     string op2 = stack.top(); stack.pop(); 
     t->root = new createOperatorNode(token[i]); 
     t->leftChild = new TreeNode(op1); 
     t->rightChild = new TreeNode(op2); 
    } 
    else { 
     stack.push(token[i]); 
    } 
}