2012-02-26 39 views
1

我编写了这个程序,它将采用中缀表示法并从中构建一个二叉树。现在唯一实际工作的输入表达式就像2 + 2.我似乎无法弄清楚如何使它处理括号并采用更长的表达式,如((2 + 2)* 3)。对于我的输出,我试图把它变成后缀表示法,并对表达式进行评估。所以,现在如果我插入2 + 2没有圆括号,我的输出是22+,它评估它,所以它打印4.Java二进制表达式树 - 检查表达式中的括号

我需要找出一种方式,打印输出与每个之间的空格数字和运算符,并让它接受带括号的较长表达式。我现在不知道如何从这里继续。任何人都可以请帮我吗?

谢谢!

这是我的代码:

class ExpressionEvaluator<T> { 

    ExpressionEvaluator() { 
     Scanner reader = new Scanner(System.in); 

     System.out.println("Enter your expression: "); 
     String expression = reader.nextLine(); // Reads the expression and trims the spaces. 
     expression = expression.replaceAll(" ", ""); 
     ExpressTree<T> tree = new ExpressTree(expression); // Creates a new binary tree. 
    } 

    public static void main(String[] args) { 
     new ExpressionEvaluator(); 
    } 
} 


interface Tree<T> { 

    // This is the tree interface with its methods. 
    public Node<T> getRoot(); 

    public void setRoot(Node<T> value); 
} 


class ExpressTree<T> implements Tree<T> { 

    private Node<T> _root; 
    private String _value, _expression; 
    private Node<T> _treeNode; 
    private Stack storage1; 
    private Stack<String> storage2; 

    public ExpressTree(String expression) { 
     expressTreeBuilder(expression);  // Calls the expressTreeBuilder method on the expression. 
     postfixTraversal(this.getRoot()); 
     System.out.println(""); 
     System.out.println(this.storage2.pop()); 
    } 

    public Node<T> getRoot() {  // Gets the root of the tree. 
     return _root; 
    } 

    public void setRoot(Node<T> _treeNode2) {  // Sets the root which will always be an operator. 
     this._root = _treeNode2; 
    } 

    public boolean isDigit(char value) { // Method to check if a value is a digit or not. 
     if (Character.isDigit(value)) { 
      return true; 
     } else { 
      return false; 
     } 
    } 

    public void expressTreeBuilder(String expression) { 

     storage1 = new Stack(); // Stores the nodes. 
     storage2 = new Stack<String>();  // Stores the value of the nodes. 
     _treeNode = new Node();  // Creates a new node 
     _value = null; 
     String next = ""; 

     for (int i = 0; i < expression.length(); i++) { 
      char traverse = expression.charAt(i); 
      if (i + 1 < expression.length()) { 
       next = Character.toString(expression.charAt(i + 1)); 
      } 

      if (traverse == '+') {  // This checks to see the expression is an addition operator. 
       Node<T> pop1, pop2;  // It pops the first 2 values from the stack and stores them 
       String value1, value2; // in pop1 and pop2. Then it uses another stack to add them. 
       pop1 = (Node<T>) storage1.pop(); 
       value1 = storage2.pop(); // Stores the right side value. 
       value2 = next; // Stores the left side value. 
       _treeNode = new Node(); 
       _treeNode.setElement(Character.toString(traverse)); 
       pop2 = new Node(); 
       pop2.setElement(next); 
       pop1.setParent(_treeNode); 
       pop2.setParent(_treeNode); 
       _treeNode.setLeftSide(pop1);  // Sets the right side of the subtree. 
       _treeNode.setRightSide(pop2);  // Sets the left side of the subtree. 
       storage1.push(_treeNode); 
       storage1.push(pop2); 
       int add = (Integer.parseInt(value2) + Integer.parseInt(value1)); 
       storage2.push(Integer.toString(add)); 
       this.setRoot(_treeNode); 
       i++; 
      } else if (traverse == '-') {  // This checks to see the expression is a subtraction operator. 
       Node<T> pop1, pop2;  // It pops the first 2 values from the stack and stores them 
       String value1, value2; // in pop1 and pop2. Then it uses another stack to subtract them. 
       pop1 = (Node<T>) storage1.pop(); 
       value1 = storage2.pop(); // Stores the right side value. 
       value2 = next; // Stores the left side value. 
       _treeNode = new Node(); 
       _treeNode.setElement(Character.toString(traverse)); 
       pop2 = new Node(); 
       pop2.setElement(next); 
       pop1.setParent(_treeNode); 
       pop2.setParent(_treeNode); 
       _treeNode.setLeftSide(pop1);  // Sets the right side of the subtree. 
       _treeNode.setRightSide(pop2);  // Sets the left side of the subtree. 
       storage1.push(_treeNode); 
       storage1.push(pop2); 
       int subtract = (Integer.parseInt(value2) - Integer.parseInt(value1)); 
       storage2.push(Integer.toString(subtract)); 
       this.setRoot(_treeNode); 
       i++; 
      } else if (traverse == '*') { // This checks to see the expression is a multiplication operator. 
       Node<T> pop1, pop2; // It pops the first 2 values from the stack and stores them 
       String value1, value2; // in pop1 and pop2. Then it uses another stack to multiply them. 
       pop1 = (Node<T>) storage1.pop(); 
       value1 = storage2.pop(); // Stores the right side value. 
       value2 = next; // Stores the left side value. 
       _treeNode = new Node(); 
       _treeNode.setElement(Character.toString(traverse)); 
       pop2 = new Node(); 
       pop2.setElement(next); 
       pop1.setParent(_treeNode); 
       pop2.setParent(_treeNode); 
       _treeNode.setLeftSide(pop1);  // Sets the right side of the subtree. 
       _treeNode.setRightSide(pop2);  // Sets the left side of the subtree. 
       storage1.push(_treeNode); 
       storage1.push(pop2); 
       int multiply = (Integer.parseInt(value2) * Integer.parseInt(value1)); 
       storage2.push(Integer.toString(multiply)); 
       this.setRoot(_treeNode); 
       i++; 
      } else if (traverse == '(') { 

      } else { 
       _treeNode = new Node(); 
       String digits = ""; 
       while (i < expression.length() && isDigit(expression.charAt(i))) { 
        digits += expression.charAt(i); // Checks if the value found at the expression is digit 
        if (digits.length() == 1) { 
         break; 
        } 
        i++; 
       } 

       _treeNode.setElement(digits);  // If it is it will set the element of the node 
       storage1.push(_treeNode);  // The node will be pushed onto the stack. 
       storage2.push(digits);   // This node will store it's value. 
      } 
     } 
    } 

    public void infixTraversal(Node<T> n) { 
     if (n != null) { 
      infixTraversal(n.getLeftSide()); 
      System.out.print(n.element() + ""); 
      infixTraversal(n.getRightSide()); 
     } 
    } 

    public void postfixTraversal(Node<T> n) { 
     if (n != null) { 
      postfixTraversal(n.getLeftSide()); 
      postfixTraversal(n.getRightSide()); 
      System.out.print(n.element()); 
     } 
    } 
} 


class Node<T> { 

    public Node<T> _left, _right, _parent; 
    private String _element; 

    public Node() { 
     this._element = null; 
     this._left = null; 
     this._right = null; 
     this._parent = null; 
    } 

    public String element() {     // Gets the value of the node. 
     return _element; 
    } 

    public Node<T> getLeftSide() {    // Gets the left side of the node. 
     return _left; 
    } 

    public Node<T> getRightSide() {    // Gets the right side of the node. 
     return _right; 
    } 

    public Node<T> getParent() {    // Gets the parent of the node. 
     return _parent; 
    } 

    public void setElement(String e) {   // Sets the value of the node. 
     _element = e; 
    } 

    public void setLeftSide(Node<T> n) {  // Sets the left side of the node. 
     _left = n; 
    } 

    public void setRightSide(Node<T> n) {  // Sets the right side of the node. 
     _right = n; 
    } 

    public void setParent(Node<T> n) {   // Sets the parent of the node. 
     _parent = n; 
    } 
} 

回答

3

您需要为您的缀表达式转换成后缀表达式正确的算法。一旦你在postfix中有了表达式,构建一个分析树或直接评估表达式就相当容易了。经典的算法是Shunting-yard algorithm,这在维基百科上有相当详细的解释。

一旦完成后缀算法,您就不必担心parathesis或运算符的优先级。这只是一堆价值观,突然冒出和推动结果。

0

有你的问题几种不同的问题:解析表达式并将其分解成一棵树

1)。你需要一个词法分析器(或词法分析器),即使是一个简单的,它需要优先级,括号等。

2)转换/评估你的树。对此有一些很好的经典算法。 3)打印结果(一旦你完成了第二部分,我怀疑它是相当简单的;这只是在正确的位置添加正确的空格和括号的问题)。

我建议阅读有关这一切现有的一些文章,让我们说,例如: