将后缀表示法转换为 ExpressionTree
Posted
技术标签:
【中文标题】将后缀表示法转换为 ExpressionTree【英文标题】:Converting a Postfix Notation to an ExpressionTree 【发布时间】:2015-02-15 19:07:56 【问题描述】:正如标题中所说,我正在尝试创建一个将后缀符号转换为表达式树的代码。在这里你可以检查构造函数:
public byte type; // 0 : operator, 1: operand (a number)
public char operator; // One of '+', '-', '*', '/'
public int operand; // A number
ExpressionTreeNode(byte type)this.type = type; left=right=null;
这是我的代码:
public static ExpressionTreeNode Postfix2ExpressionTree(String postfixExpr)
Stack s = new Stack<Object>();
ExpressionTreeNode root = new ExpressionTreeNode((byte) 0);
root.operator = postfixExpr.charAt(postfixExpr.length()-1);
String number = "";
for(int i = 0;i<postfixExpr.length()-1;i++)
if(Character.isDigit(postfixExpr.charAt(i)) == true)
number = number + postfixExpr.charAt(i);
if(Character.isDigit(postfixExpr.charAt(i+1)) == false)
ExpressionTreeNode node = new ExpressionTreeNode((byte) 1);
node.operand = Integer.valueOf(number);
node.right = null;
node.left = null;
s.push(node);
number = "";
if(i == postfixExpr.length()-2)
root.right = (ExpressionTreeNode) s.pop();
root.left =(ExpressionTreeNode) s.pop();
s.push(root);
break;
else
if(postfixExpr.charAt(i) == '+' || postfixExpr.charAt(i) == '*' || postfixExpr.charAt(i) == '-' || postfixExpr.charAt(i) == '/' )
ExpressionTreeNode node = new ExpressionTreeNode((byte)0);
node.operand = postfixExpr.charAt(i);
node.right = (ExpressionTreeNode) s.pop();
node.left = (ExpressionTreeNode) s.pop();
s.push(node);
return (ExpressionTreeNode) s.pop();
我用 charAt() 方法一一检查每个字符。简单地 1-将每个操作数压入堆栈 2-当遇到运算符时,从堆栈中弹出两个操作数并将它们分配给运算符的右侧和左侧,然后将新节点推入堆栈。 3-最后我将根压入堆栈然后返回它。
当我尝试运行时没有发生错误,但它也没有以正确的方式工作。代码我检查了很多次,但我无法解决。如果有人看到错误并帮助我,那就太好了。
【问题讨论】:
请在格式化您的代码方面付出更多努力 - 缩进现在到处都是,使其难以阅读。 “它没有以正确的方式工作”:输入是什么,它应该做什么,以及它做了什么? 请解释if(i == postfixExpr.length()-2)
的原因。
我使用了 if(i == postfixExpr.length()-2) 因为我想知道 charAt(i) 是否在堆栈的顶部。如果它在顶部,我已经定义了根,所以我可以将左右分配给根。
为什么?后缀是一种线性符号。你不需要一棵树。您可以从左到右评估它,或者直接从中生成目标代码,...
【参考方案1】:
后缀表达式是从左到右解析的——在你出现之前不要看 postfixExpr.length()-1。
不要以任何特殊方式创建和处理根节点。解析后会在栈顶。
这是一个错误:
node.operand = postfixExpr.charAt(i);
这必须存储在 node.operator 中。
这就是我将如何实现它:
public interface Entry
int evaluate();
public class Value implements Entry
private int value;
public Value( int value )
this.value = value;
public int evaluate()
return value;
public class Operation implements Entry
private char operator;
private Entry left;
private Entry right;
public Operation( char operator, Entry left, Entry right )
this.operator = operator;
this.left = left;
this.right = right;
public int evaluate()
int l = left.evaluate();
int r = right.evaluate();
switch(operator)
case '+':
return l + r;
case '-':
return l - r;
case '*':
return l * r;
case '/':
return l / r;
throw new IllegalStateException( "operator " + operator );
public class Parser
private Stack<Entry> stack = new Stack<>();
Pattern pat = Pattern.compile( "[-+*/]" );
Scanner scanner;
public void parse( String ex )
scanner = new Scanner( ex );
while( scanner.hasNext() )
while( scanner.hasNextInt() )
stack.push( new Value( scanner.nextInt() ) );
while( scanner.hasNext( pat ) )
char op = scanner.next( pat ).charAt( 0 );
Entry right = stack.pop();
Entry left = stack.pop();
stack.push( new Operation( op, left, right ) );
public Entry get()
return stack.pop();
绝对没有错误处理,所以考虑添加它。
【讨论】:
你说得对,我错过了这一点,我修复了它但仍然无法正常工作:/ 感谢代码,我也修复了我的错误,我犯的错误是使用 charAt() 检查字符串。我通过 split 方法从字符串中创建一个数组。这是正确的方式。以上是关于将后缀表示法转换为 ExpressionTree的主要内容,如果未能解决你的问题,请参考以下文章