1

I coded up this program which will take an infix notation expression and build a binary tree from it. Right now the only input expression that actually works would be like 2 + 2. I can't seem to figure out at all how to make it handle parenthesis and take in longer expressions such as ( ( 2 + 2 ) * 3 ). For my output I am trying to get it into postfix notation and also evaluate the expression. So right now if I plug in 2 + 2 without the parenthesis my output is 22+ and it evaluates it so it prints 4.

I need to figure out a way for it to print out the output with spaces in between each number and operator and also get it to accept longer expressions with parenthesis. I have no idea right now how to continue from here. Can anyone please help me out?

Thanks!

This is my code:

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;
    }
}
4

2 に答える 2

3

中置式を後置式に変換するには、適切なアルゴリズムが必要です。後置に式があれば、解析ツリーを作成したり、式を完全に評価したりするのはかなり簡単です。古典的なアルゴリズムは分流場アルゴリズムで、ウィキペディアで非常に詳細に説明されています。

postfix へのアルゴリズムが完了すると、パラセシスや演算子の優先順位について心配する必要がなくなります。それは単なる値のスタックであり、結果をポップおよびプッシュします。

于 2012-02-26T14:03:22.303 に答える
0

あなたの質問にはいくつかの異なる問題があります:

1) 式を解析し、ツリーに分解します。これにはレクサー(またはトークナイザー)が必要です。単純なものであっても、優先順位や括弧などが必要です。

2) ツリーの変換/評価。これには、優れた古典的アルゴリズムがいくつかあります。

3) 結果を出力します (パート 2 が完了すれば、かなり簡単だと思います。適切な場所に正しい空白と括弧を追加するだけです)。

これらすべてに関する既存の記事を読むことをお勧めします。たとえば、次のようにします。

于 2012-02-26T14:32:26.240 に答える