1

I dont understand how to do this? Can someone please explain how to convert, for example, ac+ ac+*into a binary tree form?? I need to turn this expression into a full parenthesized string representation of this tree.

AayushK
  • 73
  • 3
  • 10
  • Can you please add more details to your question? E.g. which is the desired output for the sample input. Do you need a generic algorithm or a generic implementation in Java (I see you added a tag)? – Andrei Nicusan Nov 10 '13 at 21:28
  • a generic implementation in java – AayushK Nov 10 '13 at 21:31
  • Please stop calling it RPN; its not even the proper name for that style, and it is stupidly long. Call it "postfix", please. Also, parenthesis are stupid. Once you grok the postfix, it is actually easier to understand than the usual parenthesis hurricane. – AJMansfield Nov 10 '13 at 22:21

2 Answers2

5

You need to build the tree just the way you would process the postfix input. However, when you encounter an operation, instead of calculating the value, you make the arguments on the stack the children of the operator node. Then you push it on the stack (just as you would push the calculation result on the stack in postfix notation).

At the end, the only element on the stack should be the root of the complete tree.

Should look roughly like this:

public class Node {
    char value;
    Node left, right;

    public Node(char value) {
        this.value = value;
    }

    public static Node parseUpn(String s) {
        Stack<Node> stack = new Stack<Node>();

        for (char c: s.toCharArray()) {
            if (c != ' ') {
                Node node = new Node(c);
                if ("+-*/".indexOf(c) != -1) { 
                    node.right = stack.pop();
                    node.left = stack.pop();
                }
            }
            stack.push(node);
        }

        if (stack.size() != 1) {
            throw new RuntimeException("Expected exactly one stack value.");
        }
        return stack.pop();
    }

    @Override
    public String toString() {
        return left == null ? String.valueOf(value) : 
             ("(" + left + " " + value + " " + right + ")");
    }
}
Stefan Haustein
  • 18,427
  • 3
  • 36
  • 51
  • What about multiple-character operations, like `**` (for exponentiation), or operations that have more than 2 children (an `if?then:else` operation requires 3 children) – AJMansfield Nov 10 '13 at 22:33
  • Sorry did I overlook something int the example? How do you know "**" is not 2x multiplication? IIRC in Forth you have them separated by whitespace, so in that case you could just use String.split()... But the example only makes sense if ac is treated as two separate variables.... – Stefan Haustein Nov 10 '13 at 22:38
  • True! actually you couldn't use `**` as exponentiation if you were using ``* for multiplication! Although, it could still apply in other situations. For instance, in PostScript the operators are `add`, `sub`, `mul`, and the like, rather than single characters, – AJMansfield Nov 10 '13 at 22:46
  • And the ternary operator still remains. – AJMansfield Nov 10 '13 at 22:48
  • Well the code also does not handle unary operators... But making this part of the problem without more information is just speculation... – Stefan Haustein Nov 10 '13 at 22:55
-3

I am going to use a class Node to represent the nodes of the tree. All my node needs is the following:

public interface Node<T> {
    public void addChild(Node<T>);
}

We will assume I have an implementing class TreeNode<T> that has a constructor public TreeNode(T value).

I am going to assume that you have already chopped up the string and parsed all the characters in some other method, so that you have an array of Tokens that represent the expression:

public interface Token {

    /**
     * @return The number of operands this token takes.
     * A return value of 0 indicates this token does not
     * take any operands.
     */
    public int getOperandCount();

}

(It may be desirable to include additional methods in your classes, so that you can read the values from the tree, but that is not strictly necessary to build it.)

Also,

public class MalformedExpressionException extends IllegalArgumentException{
    public MalformedExpressionException(String reason){/* [ ... ] */};
    // [ ... ]
}

With that out of the way, the following function will produce you a tree, returning its root node.

public static Node<Token> makeTree(Token [] tokens){
    Stack<Node<Token>> stack = new Stack<>();

    try{
        for(Token t:tokens){
            Node<Token> node = new TreeNode<Token>(t);
            for(int idx = 0; idx < t.getOperandCount(); idx++)
                node.addChild(stack.pop());
            stack.push(node);
        }
    }catch (EmptyStackException e){
        throw new MalformedExpressionException("too few operands");
    }

    if(stack.size() != 1)
        throw new MalformedExpressionException("too many operands");

    return stack.pop();
}
AJMansfield
  • 4,039
  • 3
  • 29
  • 50
  • In order to encourage learning, ou should know that, I hold copyright to all the code in my answer. (It is released under a [Creative Commons Attribution-ShareAlike 3.0 Unported License](http://creativecommons.org/licenses/by-sa/3.0/).) If you hand any of the code I wrote in to your programming class, as is, then you are breaking copyright law unless you indicate that _I_ wrote it. So please, actually do your own work. – AJMansfield Nov 10 '13 at 22:08
  • Now, if you actually understand the code I gave above, then making the part that traverses the tree and builds up the parentheticated expression should be extremely easy. – AJMansfield Nov 10 '13 at 22:15
  • See the [Legal link](http://stackexchange.com/legal). You have already given SO a perpetual license, and the OP has a right to download for personal use under the same terms. – user207421 Nov 10 '13 at 22:19
  • @EJP Yes, I am aware of that. I actually just looked it up to check what the licensing requirements were. I am saying that if he uses it for his classwork, he has to put my name on it. The point being not to restrict the use, but to ensure that he doesn't just copy-paste code. (I intend to release it fully a few days from now, anyway) – AJMansfield Nov 10 '13 at 22:28