在Java中将波兰语反转为中缀表示法优化

时间:2018-09-01 16:30:55

标签: java algorithm optimization infix-notation

我正在尝试解决涉及将逆向抛光表示法转换为中缀表示法的编程难题。例如: 1 3 + 2 4 5-+ /将是:((1 + 3)/(2+(4-5))) 到目前为止,我的解决方案确实有效,但是速度不够快。因此,我正在寻找任何优化建议。

public class betteralgo {
    public static void main(String[] args) throws IOException {
        BufferedReader bi = new BufferedReader(new InputStreamReader(System.in));
        String line = bi.readLine();
        String[] input = line.split(" ");
        StringBuilder builder = new StringBuilder();
        Stack<String> stack = new Stack<String>();

        for(String e:input) {
            switch(e){
                case("+"):
                case("-"):
                case("*"):
                case("/"):
                    String i = stack.pop();
                String k = stack.pop();
                stack.push("(" + k + e + i + ")");
                break;
                default:
                    stack.push(e);
                }
            }
        System.out.println(stack.pop());        
        }       
    }

3 个答案:

答案 0 :(得分:1)

您的问题是由于使用越来越长的表达式而导致的二次复杂性。解决方案是建立一棵树。代替

"(" + k + e + i + ")"

创建一个新的节点,其内容为e,子节点为ki。然后,通过树的简单传递即可生成任何表示形式(中缀,前缀或后缀)。

答案 1 :(得分:0)

您的代码的时间复杂度为O(n),对于我认为的此问题,这可能是最快的。但是您没有利用StringBuilder的优势,而是使用了耗时的字符串连接。

以下是优化版本:

public static void main(String[] args) throws IOException {
    BufferedReader bi = new BufferedReader(new InputStreamReader(System.in));
    String line = bi.readLine();
    String[] input = line.split(" ");
    StringBuilder builder = new StringBuilder();
    Stack<String> stack = new Stack<String>();

    for(String e:input) {
        switch(e) {
            case("+"):
            case("-"):
            case("*"):
            case("/"):
                String i = stack.pop();
                String k = stack.pop();
                builder.setLength(0);
                builder.append("(");
                builder.append(k).append(e).append(i);
                builder.append(")");
                stack.push(builder.toString());
                break;
            default:
                stack.push(e);
        }
    }
    System.out.println(stack.pop());  
}

答案 2 :(得分:0)

只是出于好奇,这种递归解决方案会更快吗?

public static void main(String[] args)
{
    String input = "1 3 + 2 4 5 - + /";
    List<String> terms = new ArrayList<>(Arrays.asList(input.split(" ")));      
    String result = build(terms);
    System.out.println(result);
}

static String build(List<String> terms)
{
    String t = terms.remove(terms.size()-1);        
    if("+-/*".indexOf(t) >= 0)
    {
        String op2 = build(terms);
        String op1 = build(terms);
        return "(" + op1 + t + op2 + ")";
    }
    else return t;
}