有关如何将表达式树转换为后缀表示法的足够资源,并不是那么难.
但我必须将后缀表达式解析为表达式树.
表达式是:
A 2 ^ 2 A*B* - B 2 ^ + AB - /
我真的不知道如何解释表达式.有人知道如何处理这个问题吗?
创建一个包含可能是树的一部分的节点的堆栈
将堆栈上的操作数(A,2,B等操作数)推送为叶节点,不绑定到任何方向的任何树
对于运算符,从堆栈中弹出必要的操作数,在顶部创建一个操作符,并在其下方挂起操作数,将新节点推入堆栈
对于您的数据:
将A推入堆栈
将2推入堆栈
弹出2和A,创建^ -node(下面有A和2),将其推入堆栈
在堆栈上按2
在堆栈上按A
弹出A和2并组合形成*-node
等等
等等
这是一个LINQPad程序,可以通过以下方式进行实验:
// 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; } }
输出:
这看起来是否正确:
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 - /
在你的声明上运行它应该产生一个这样演变的堆栈:
[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]