Search code examples
javarecursionprefixpostfix-notation

Converting a prefix expression to postfix


I'm trying to implement a program that changes a prefix expression to a postfix one using recursion.

I've written what I thought would work but instead of the output ab/c*de+f*- I get aa/aa/*aa/aa/*- instead.

I think my code is getting stuck when I try to get the first character of String pre or when I try to delete the first character of String pre. Any suggestions/comments?

  public class Prefix2Postfix {
        public static final String prefixInput ="-*/abc*+def";
        //desired postfix output is "ab/c*de+f*-"

        public static void main (String[] args){
            System.out.println(pre2Post(prefixInput));
        }

        public static String pre2Post(String pre){
            //find length of string
            int length = pre.length();

            //ch = first character of pre
            char ch = pre.charAt(0);

            //delete first character of pre
            pre = pre.substring(1,length);
            if(Character.isLetter(ch)){
                //base case: single identifier expression
                return (new Character(ch)).toString(ch);
            }else{ 
                //ch is an operator
                String postfix1 = pre2Post(pre);
                String postfix2 = pre2Post(pre);
                return postfix1 + postfix2 + ch;
            }
        }
    }

Solution

  • So the error in your code has to do with where you calculate postfix1 and postfix2 -- note that you're not offsetting postfix2.

    To do this recursion you need to understand a few cases:

    • When you encounter an operator you need to recurse and move the operator to the right, and then process any remaining portion of the string that has not been processed
    • When you encounter a letter and an operator you should just return the letter
    • When you encounter two letters, you should just return those two letters

    This means when you encounter something like +-abc you will do the following steps:

    f("+-abc") => return f("-abc") + "+" + f(rem1)
     f("-abc") => return f("abc") + "-" + f(rem2)
      f("abc") => return "ab"
      rem2 = "c" (remainder of the string)
      f("c")   => return "c"
     rem1 = ""   (nothing left in the string to parse)
    
    which constructs "ab-c+"
    

    This should work:

    public static String pre2post(String pre){
        if(pre.length() <= 1){
            return pre;
        }
    
        if(!Character.isLetter(pre.charAt(0))){
            String a = pre2post(pre.substring(1)) + pre.charAt(0);
            String b = pre2post(pre.substring(a.length()));
            return a + b;
        }else if(!Character.isLetter(pre.charAt(1))){
            return pre.substring(0,1);
        }else{
            return pre.substring(0,2);
        }
    
    }