简体   繁体   English

将中缀表达式读入堆栈

[英]Read infix expression into a stack

I've written code to convert an expression tree to preorder and postorder, but I'm struggling to actually build the expression tree from an infix expression. 我已经编写了将表达式树转换为前置和后置顺序的代码,但是我正在努力从infix表达式中构建表达式树。 I have a .cc file that will call the build_expression_tree function, call the conversion functions and print out the converted expressions. 我有一个.cc文件,它将调用build_expression_tree函数,调用转换函数并打印出转换后的表达式。

This is my current non-working function: 这是我目前无法使用的功能:

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

The errors I'm getting at this point are: Expression_Tree.h:61:40: error: ISO C++ forbids comparison between pointer and integer 我现在遇到的错误是:Expression_Tree.h:61:40:错误:ISO C ++禁止比较指针和整数

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

Expression_Tree.h:62:13: error: 'temp' was not declared in this scope Expression_Tree.h:62:13:错误:在此范围内未声明“ temp”

temp->right = tree_stack.top();

Expression_Tree.h:62:13: error: 'temp' was not declared in this scope Expression_Tree.h:62:13:错误:在此范围内未声明“ temp”

temp->left = tree_stack.top();

I know why the last two errors (not declared in scope) are occurring, but I just don't know what to do to fix it whilst making my code work properly. 我知道为什么发生最后两个错误(未在作用域中声明),但我只是不知道该如何解决才能使我的代码正常工作。

I don't even know if my code is completely wrong, but any tips would be incredibly appreciated! 我什至不知道我的代码是否完全错误,但是任何提示都会令人难以置信! Thanks. 谢谢。

EDIT: These are the classes that affect the Build_Expression_Tree function. 编辑:这些是影响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*);
};

A quick look reveals that you need a ETNode *temp = new ETNode; 快速了解一下,您需要一个ETNode *temp = new ETNode; just after while(tree_stack.top() != '(') . I did not check the logic, though. 就在while(tree_stack.top() != '(') ,不过我没有检查逻辑。

Here I've split up your example input into a representation of how the stack can be used and the decisions made at each input. 在这里,我将您的示例输入分成了如何使用堆栈以及在每个输入处做出决策的表示形式。

//    _ = 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

Note that I have many duplicate statements, one type for ( one for ) one for a number 0-9 and one for each operation +-*/ . 请注意,我有很多重复的语句,一种表示(一种表示)类型,一种表示数字0-9 ,另一种表示每种操作+-*/ You already have these divisions in your code so you're on the right track. 您的代码中已经包含了这些划分,因此您走在正确的轨道上。

( 's only job should be to create a new node on the top of the stack. In your code, there is no point to set input = '(' because its going to be overwritten by an actual input later and its position in the stack is all that's needed to keep track of it. You should initialize input to '\\0' or something else meaning empty. (的唯一工作应该是在堆栈的顶部创建一个新节点。在您的代码中,没有必要设置input = '('因为稍后它会被实际的输入覆盖,并且其位置在堆栈是跟踪记录所需的全部,您应该将input初始化为'\\0'或其他意味着为空的东西。

) 's job should be to pop the top off the stack and put it where it needs to go. )的工作应该是将栈顶弹出堆栈,并将其放在需要放置的地方。 That'll be either the next top's left node if its null, otherwise it'll be top's right node. 如果为null,则它将是下一个顶部的左节点,否则它将是顶部的右节点。 You don't need to loop down the stack like you do, because it'll always just be the top that we're interested in popping. 您不需要像您一样循环遍历堆栈,因为它始终只是我们感兴趣的弹出窗口的顶部。

A number's job should be to create itself as a new node and put itself where it needs to go. 数字的工作应该是将自己创建为新节点,并将其放置在需要移动的位置。 Just like ) that'll either be the top's left node if its null, otherwise it'll be top's right node. 就像)那将或者是顶部的左节点如果为空,否则这将是顶级的右节点。 In your code, you make the node but you don't put it anywhere besides on the stack. 在您的代码中,您创建了节点,但没有将其放置在堆栈上的任何地方。 Its not doing any good there because a number node will always be a leaf node (no right or left). 它在那里没有任何用处,因为数字节点将始终是叶节点(无左无右)。

Finally an operation's job should be to simply set itself to the top's input . 最后,操作的工作应该是简单地将自身设置为顶部的input However, there's a special case where the top has already been filled in (when you do 1+2+3 the 1+2 is the node on top). 但是,在特殊情况下,顶部已被填充(当您执行1+2+31+2是顶部的节点)。 So what you can do in that case is pop off the top, push a new node on top, add the old top as the left, and THEN just set itself to top's input . 因此,在这种情况下,您可以做的是从顶部弹出,在顶部推一个新节点,在左侧添加旧顶部,然后将自身设置为顶部的input You don't need a loop. 您不需要循环。

After all is done, you can just set root = tree_stack.top() . 完成所有操作后,您只需设置root = tree_stack.top()

If you want the code I can supply it but I hope my explanation is enough. 如果您想要该代码,我可以提供,但希望我的解释足够。

Code: This seems to work for me 代码:这似乎对我有用

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM