将中缀表达式读入堆栈

时间:2016-05-11 05:28:36

标签: c++ stack expression-trees infix-notation

我已编写代码将表达式树转换为预订和后序,但我正在努力从中缀表达式实际构建表达式树。我有一个.cc文件,它将调用build_expression_tree函数,调用转换函数并打印出转换后的表达式。

这是我目前的非工作职能:

void Expression_Tree::build_expression_tree(char input[], int size)
{
    for (int i = 0; i < size; i++) 
    {
        if (input[i] == ' ')
        {
            i++;
        }
        if(input[i] >= '0' && input[i] <= 9) 
        { 
            ETNode *temp = new ETNode;
            temp->left = temp->right = NULL;
            temp->input = input[i];

            tree_stack.push(temp);
        }
        else if (input[i] == '(') 
        {
            ETNode *temp = new ETNode;
            temp->left = temp->right = NULL;
            temp->input = input[i];

            tree_stack.push(temp);
        }
        else if (input[i] == ')')
        {
            while (tree_stack.top() != '(')
            {
                temp->right = tree_stack.top();
                tree_stack.pop();
                temp->left = tree_stack.top();
                tree_stack.pop();
                tree_stack.pop();
                tree_stack.push(temp);
            }
        }
        else if (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/')
        {
            while (!tree_stack.empty())
            {
                ETNode *temp = new ETNode;
                temp->left = temp->right = NULL;
                temp->input = input[i];

                tree_stack.push(temp);

                temp->right = tree_stack.top();
                tree_stack.pop();
                temp->left = tree_stack.top();
                tree_stack.pop();

                tree_stack.push(temp);
            }
        }
    }
}

此时我遇到的错误是: Expression_Tree.h:61:40:错误:ISO C ++禁止指针和整数之间的比较

while(tree_stack.top() != '(')

Expression_Tree.h:62:13:错误:&#39; temp&#39;未在此范围内声明

temp->right = tree_stack.top();

Expression_Tree.h:62:13:错误:&#39; temp&#39;未在此范围内声明

temp->left = tree_stack.top();

我知道为什么最后两个错误(未在范围中声明)正在发生,但我只是不知道如何修复它同时使我的代码正常工作。

我甚至不知道我的代码是否完全错误,但任何提示都会非常感激! 谢谢。

编辑: 这些是影响Build_Expression_Tree函数的类。

class ETNode {
public:
    char input;
    ETNode *left, *right;
};

class Expression_Tree { 
public:
    Expression_Tree() { root = 0; };
    ~Expression_Tree() { clear(root); }
    void build_expression_tree(char[], int);
    void inorder() { inorder(root); }
    void preorder() { preorder(root); }
    void postorder() {postorder(root); }
private:
    ETNode* root;
    std::stack<ETNode*> tree_stack;
    void visit(ETNode* p) { std::cout << p->input << " "; } 
    void inorder(ETNode*);
    void preorder(ETNode*);
    void postorder(ETNode*);
    void clear(ETNode*);
};

2 个答案:

答案 0 :(得分:0)

快速浏览一下,ETNode *temp = new ETNode;之后您需要while(tree_stack.top() != '(')。不过,我没有检查逻辑。

答案 1 :(得分:0)

在这里,我将您的示例输入拆分为如何使用堆栈以及在每个输入处做出的决策的表示。

//    _ = nullptr or empty
//    # = pointer to subtree (not just a number)
// | ___ |     |     |     begin (empty element on stack)
// | 2__ |     |     |  2  make number node and set to top->left if empty, else top->right
// | 2+_ |     |     |  +  set top->input if not set, else pop parent into left of new node
// | 2+_ | ___ |     |  (  make new node on stack
// | 2+_ | 3__ |     |  3  make number node and set to top->left if empty, else top->right
// | 2+_ | 3*_ |     |  *  set top->input if not set, else pop parent into left of new node
// | 2+_ | 3*_ | ___ |  (  make new node on stack
// | 2+_ | 3*_ | 2__ |  2  make number node and set to top->left if empty, else top->right
// | 2+_ | 3*_ | 2+_ |  +  set top->input if not set, else pop parent into left of new node
// | 2+_ | 3*_ | 2+2 |  2  make number node and set to top->left if empty, else top->right
// | 2+_ | 3*# |     |  )  pop it off into its parent
// | 2+# |     |     |  )  pop it off into its parent
// | #+_ |     |     |  +  set top->input if not set, else pop parent into left of new node
// | #+5 |     |     |  5  make number node and set to top->left if empty, else top->right

请注意,我有许多重复的陈述,(的一种类型)一种0-9一种+-*/一种,每种操作(一种。您已经在代码中使用了这些部门,以便您处于正确的轨道上。

input = '('唯一的工作应该是在堆栈顶部创建一个新节点。在您的代码中,没有必要设置input,因为它稍后会被实际输入覆盖,并且它在堆栈中的位置是跟踪它所需的全部内容。您应该将'\0'初始化为)或其他意味着为空的内容。

)的工作应该是从堆栈顶部弹出并将其放在需要去的地方。如果它是null,那么它将是下一个顶部的左边节点,否则它将是顶级的右边节点。你不需要像你一样循环堆栈,因为它总是只是我们对弹出感兴趣的顶级。

一个数字的工作应该是将自己创建为一个新节点,并将自己置于需要去的地方。就像input一样,如果它是null,那么它将是顶部的左边节点,否则它将是顶级的右边节点。在您的代码中,您创建节点,但除了堆栈之外,您不能将它放在任何地方。它没有任何好处,因为数字节点将始终是叶节点(没有右或左)。

最后,一项操作的工作应该是将自己设置为顶级1+2+3。但是,有一个特殊情况,其中已经填写了顶部(当您1+2时,input是顶部的节点)。那么你在这种情况下可以做的就是从顶部弹出,在顶部推一个新节点,在左边添加旧顶部,然后将自己设置为顶部root = tree_stack.top()。你不需要循环。

完成所有操作后,您只需设置void Expression_Tree::build_expression_tree(char input[], int size) { // assuming empty tree_stack, it shouldn't really be a member // variable since its only used for building //std::stack<ETNode*> tree_stack; // make empty node, should really make a default constructor set all this up tree_stack.push(new ETNode); tree_stack.top()->left = nullptr; tree_stack.top()->right = nullptr; tree_stack.top()->input = '\0'; for (int i = 0; i < size; i++) { if (input[i] == ' ') { i++; } if (input[i] >= '0' && input[i] <= '9') // this 9 had a typo before { // create number leaf ETNode *temp = new ETNode; temp->left = nullptr; temp->right = nullptr; temp->input = input[i]; // put where it needs to go if (tree_stack.top()->left == nullptr) tree_stack.top()->left = temp; else tree_stack.top()->right = temp; } else if (input[i] == '(') { // make empty node ETNode *temp = new ETNode; temp->left = nullptr; temp->right = nullptr; temp->input = '\0'; tree_stack.push(temp); } else if (input[i] == ')') { // pop top from the stack ETNode *temp = tree_stack.top(); tree_stack.pop(); // put where it needs to go if (tree_stack.top()->left == nullptr) tree_stack.top()->left = temp; else tree_stack.top()->right = temp; } else if (input[i] == '+' || input[i] == '-' || input[i] == '*' || input[i] == '/') { // shuffle node if already filled if (tree_stack.top()->input != '\0') { ETNode *old = tree_stack.top(); tree_stack.pop(); ETNode *temp = new ETNode; temp->left = old; temp->right = nullptr; tree_stack.push(temp); } tree_stack.top()->input = input[i]; } } // set root node root = tree_stack.top(); } 即可。

如果你想要我可以提供的代码,但我希望我的解释已经足够了。

代码:这似乎对我有用

getDropDown