1

표현 트리의 빌드를 시도하는 두통, 특히 treenode 포인터를 구현하는 방법에 대한 단서가없고 실제적으로 있어야 할 데이터를 저장할 노드를 만드는 데 문제가 있습니다. 꽤 기본하지만 코드는 단지 나를 혼란스럽게합니다. 예를 들어표현 트리 구현 문제

, 내가 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

파싱 표현하는 가장 쉬운 방법은 재귀 하강 파서를 구축하는 것입니다. 이것은 expression, term 및 factor라고하는 상호 재귀 함수로 구성됩니다. 요소는 기본 단위 또는 열려있는 괄호, 표현식, 닫는 괄호 중 가장 작은 단위입니다 (상호 재귀가 들어옴). 용어는 곱하기 및 나눗셈 연산자를 사용하는 요인 모음이며, 표현식은 더하기 및 빼기 연산자로 결합 된 용어 모음입니다.

단항 마이너스의 경우 특별한 규칙이 필요합니다.

이제 재귀 적 하향 파서는 실제로 메모리의 구조로 트리를 작성하지 않습니다. 트리는 호출 패턴에 함축되어 있습니다. 그러나 나무를 원하면 쉽게 수정할 수 있습니다.

그것은 나의 매우 간단한 기본 인터프리터 당신은 단순히 TreeNode.h 당신을주는 무슨 사용

https://github.com/MalcolmMcLean/minibasic

0

에서 살펴 봐야 도움이 될 수 있습니다. 당신이 5 + 5를 나타내는 이름 root와 트리를 만들려면 예를 들어

이, 당신이 파서 내에서

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를 내부 클래스로 가지는 클래스 Tree를 만들고 TreeNode의 생성자와 소멸자가 Private (Tree를 친구로하여) 인 Tree와 TreeNode를 분리하는 것이 좋습니다. 사물에 대한 통제권을 부여합니다. setLeftChild와 같은 작업은 잘못 수행되면 메모리 누수와 관련하여 위험 할 수 있으며 트리를 생각하지 않는 루프를 만들 수 있습니다.

0

먼저 표현식을 후위 표현식 (Infix To Postfix)으로 변환하십시오.

표현 :5 + 5

후위 :5 5 +

그런 다음 접미사 문자열을 구문 분석 할 때마다 당신은 피연산자 스택에 밀어 넣습니다 찾거나 당신이 연산자를 발견하면 다음 두 개의 피연산자를 팝업 스택에서 (이진 연산자 인 경우) 트리 루트를 연산자 왼쪽에 & 피연산자로 할당합니다.

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