Postfix notation to expression tree

匿名 (未验证) 提交于 2019-12-03 08:28:06

问题:

There are enough resources on how to convert an expression tree into postfix notation, and it's not that hard.

But I have to parse a postfix expression into an expression tree.

The expression is:

A 2 ^ 2 A * B * - B 2 ^ + A B - /

I don't really have a clue on how to interpret the expression. Does someone has a clue on how to proces this?

回答1:

Create a stack containing nodes that could be part of a tree

  1. Push operands on a stack (A, 2, B, etc. are operands) as leaf-nodes, not bound to any tree in any direction
  2. For operators, pop the necessary operands off the stack, create a node with the operator at the top, and the operands hanging below it, push the new node onto the stack

For your data:

  1. Push A onto the stack
  2. Push 2 onto the stack
  3. Pop 2 and A, create ^-node (with A and 2 below), push it on the stack
  4. Push 2 on stack
  5. Push A on stack
  6. Pop A and 2 and combine to form the *-node
  7. etc.
  8. etc.

Here is a LINQPad program that can be experimented with:

// Add the following two using-directives to LINQPad: // System.Drawing // System.Drawing.Imaging  static Bitmap _Dummy = new Bitmap(16, 16, PixelFormat.Format24bppRgb); static Font _Font = new Font("Arial", 12);  void Main() {     var elementsAsString = "A 2 ^ 2 A * B * - B 2 ^ + A B - / 2 ^";     var elements = elementsAsString.Split(' ');      var stack = new Stack();     foreach (var element in elements)         if (IsOperator(element))         {             Node rightOperand = stack.Pop();             Node leftOperand = stack.Pop();             stack.Push(new Node(element, leftOperand, rightOperand));         }         else             stack.Push(new Node(element));      Visualize(stack.Pop()); }  void Visualize(Node node) {     node.ToBitmap().Dump(); }  class Node {     public Node(string value)         : this(value, null, null)     {     }      public Node(string value, Node left, Node right)     {         Value = value;         Left = left;         Right = right;     }      public string Value;     public Node Left;     public Node Right;      public Bitmap ToBitmap()     {         Size valueSize;         using (Graphics g = Graphics.FromImage(_Dummy))         {             var tempSize = g.MeasureString(Value, _Font);             valueSize = new Size((int)tempSize.Width + 4, (int)tempSize.Height + 4);         }          Bitmap bitmap;         Color valueColor = Color.LightPink;         if (Left == null && Right == null)         {             bitmap = new Bitmap(valueSize.Width, valueSize.Height);             valueColor = Color.LightGreen;         }         else         {             using (var leftBitmap = Left.ToBitmap())             using (var rightBitmap = Right.ToBitmap())             {                 int subNodeHeight = Math.Max(leftBitmap.Height, rightBitmap.Height);                 bitmap = new Bitmap(                     leftBitmap.Width + rightBitmap.Width + valueSize.Width,                     valueSize.Height + 32 + subNodeHeight);                  using (var g = Graphics.FromImage(bitmap))                 {                     int baseY  = valueSize.Height + 32;                      int leftTop = baseY; // + (subNodeHeight - leftBitmap.Height) / 2;                     g.DrawImage(leftBitmap, 0, leftTop);                      int rightTop = baseY; // + (subNodeHeight - rightBitmap.Height) / 2;                     g.DrawImage(rightBitmap, bitmap.Width - rightBitmap.Width, rightTop);                      g.DrawLine(Pens.Black, bitmap.Width / 2 - 4, valueSize.Height, leftBitmap.Width / 2, leftTop);                     g.DrawLine(Pens.Black, bitmap.Width / 2 + 4, valueSize.Height, bitmap.Width - rightBitmap.Width / 2, rightTop);                 }             }         }          using (var g = Graphics.FromImage(bitmap))         {             float x = (bitmap.Width - valueSize.Width) / 2;             using (var b = new SolidBrush(valueColor))                 g.FillRectangle(b, x, 0, valueSize.Width - 1, valueSize.Height - 1);             g.DrawRectangle(Pens.Black, x, 0, valueSize.Width - 1, valueSize.Height - 1);             g.DrawString(Value, _Font, Brushes.Black, x + 1, 2);         }          return bitmap;     } }  bool IsOperator(string s) {     switch (s)     {         case "*":         case "/":         case "^":         case "+":         case "-":             return true;          default:             return false;     } } 

Output:



回答2:

Does this look correct:

for n in items:     if n is argument:         push n     if n is operator:         b = pop      // first pop shall yield second operand            a = pop      // second pop shall yield first operand         push a+n+b  answer = pop    A 2 ^ 2 A * B * - B 2 ^ + A B - / 

Running this on your statment should yield a stack that evolves like this:

[A] [A, 2] [A^2] [A^2, 2] [A^2, 2, A] [A^2, 2*A] [A^2, 2*A, B] [A^2, 2*A*B] [A^2-2*A*B] [A^2-2*A*B, B] [A^2-2*A*B, B, 2] [A^2-2*A*B, B^2] [A^2-2*A*B+B^2] [A^2-2*A*B+B^2, A] [A^2-2*A*B+B^2, A, B] [A^2-2*A*B+B^2, A-B] [A^2-2*A*B+B^2/A-B] 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!