将后缀表示法转换为ExpressionTree

时间:2014-12-17 09:24:10

标签: java stack expression-trees postfix-notation

正如标题中所说,我正在尝试创建一个将后缀表示法转换为表达式树的代码。在这里你可以检查构造函数:

  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 - 将每个操作数推入堆栈 当遇到操作符时,从堆栈中弹出两个操作数并将它们分配给操作符的左右两侧,然后将新节点推送到堆栈。 3-然后我将根推到堆栈然后返回它。

当我尝试运行时没有发生错误,但也没有以正确的方式工作。我多次查看代码,但我无法解决。如果有人看到错误并帮助我,那就太棒了。

1 个答案:

答案 0 :(得分:0)

从左到右解析后缀表达式 - 在你到达之前不要看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();
  }
}

绝对没有错误处理,所以考虑添加它。