【问题标题】:infix to postfix in java using stack class使用堆栈类在java中后缀的中缀
【发布时间】:2015-05-09 06:57:33
【问题描述】:

我正在尝试使用堆栈将中缀写入 java 中的后缀程序。这是我的代码:

import java.io.*;
import java.util.*;
public class ONP{
        public static void main(String args[]) throws java.io.IOException, NumberFormatException ,EmptyStackException{
            BufferedReader br= new BufferedReader(new InputStreamReader(System.in));

            int n=Integer.parseInt(br.readLine());
            StringBuilder out= new StringBuilder();

            Stack st=new Stack();

            for(int i=0;i<n;i++){
                String input=br.readLine();
                char in[]=input.toCharArray();
                int len=input.length();
                for (int j=0;j<len;j++){
                    if (in[j]>='a' && in[j]<='z'){
                        out.append(in[j]);
                    }

                    else if(in[j]=='('){
                        st.push(new Character(in[j]));

                    }
                    else if(in[j]=='+' || in[j]=='-' || in[j]=='*' || in[j]=='/' || in[j]=='^'){
                        st.push(new Character(in[j]));

                    }

                    else if(in[j]==')'){
                        int k=j;

                        while(in[k]!='(' && !st.empty() ){

                            char ch=st.pop().toString().charAt(0);
                            if(ch!='('&&ch!=')')
                             out.append(ch);
                            k--;
                        }
                    }


                }
                out.append("\n");

            }
            System.out.print(out);
        }
}

输入:

 ((a+t)*((b+(a+c))^(c+d)))

输出:

 at+bac++*cd+^

“*”应该在“+^”之后,但它应该在“++”之后。我找不到错误。

【问题讨论】:

    标签: java stack infix-notation


    【解决方案1】:

    好吧,您需要实现运算符优先级,而您没有。您需要查找 Dijkstra Shutting-yard 算法。

    【讨论】:

    • 此特定示例不是优先级问题,因为 OP 示例具有括号,即使没有优先级,也可以使计算顺序明确且明确。不过,实施优先级将是一个很好的下一步。
    【解决方案2】:

    这只是一个小错误。 在此代码中,您在“in”数组中查找 '(',这是没有意义的。您只想在堆栈中查找它。

    else if(in[j]==')'){
        int k=j;
    
        while(in[k]!='(' && !st.empty() ){
    
            char ch=st.pop().toString().charAt(0);
            if(ch!='('&&ch!=')')
             out.append(ch);
            k--;
        }
    }
    

    改成这个就行了

    else if(in[j]==')'){
        while(!st.empty() ){
            char ch=st.pop().toString().charAt(0);
            if(ch == '(') break;
            out.append(ch);
        }
    }
    

    这应该可以解决错误。但是还有很多其他细节可以改进。例如将部分代码放入另一个方法中,并使用泛型和自动装箱。使用字符串而不是字符来允许具有多个字符的运算符并实现运算符优先级,因此您不需要那么多括号。

    看看这个。

    import java.io.*;
    import java.util.*;
    import java.util.regex.*;
    
    public class ONP {
            private static int precedence(String operator) {
                switch(operator) {
                    case "(": return 0;
                    case "+": case "-": return 1;
                    case "*": case "/": return 2;
                    case "^": return 3;
                    case "sin": case "cos": return 4;
                    default: return -1;
                }
            }
    
            private static List<String> tokenize(String input) {
                ArrayList<String> tokens = new ArrayList<>();
                Pattern p = Pattern.compile("\\(|\\)|[A-Za-z]+|\\d*\\.\\d*|\\d+|\\S+?");
                Matcher m = p.matcher(input);
                while(m.find()) {
                  tokens.add(m.group());
                }
                return tokens;
            }
    
            private static List<String> toPostfix(List<String> infix) {
                Stack<String> st = new Stack<>();
                ArrayList<String> out = new ArrayList<>();
                for(String s: infix) {
                    if(s.equals("(")){
                        st.push(s);
                    } else if(s.equals(")")){
                        while(!st.empty() ){
                            String s2 = st.pop();
                            if(s2.equals("(")) break;
                            out.add(s2);
                        }
                    } else if(precedence(s) > 0) {
                        int p = precedence(s);
                        while(!st.isEmpty() && precedence(st.peek()) >= p) out.add(st.pop());
                        st.push(s);
                    } else {
                        out.add(s);
                    }
                }
                while(!st.isEmpty()) out.add(st.pop());
                return out;
            }
    
            public static void main(String args[]) throws java.io.IOException, NumberFormatException ,EmptyStackException{
                BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
                int n=Integer.parseInt(br.readLine());
                for(int i=0;i<n;i++){
                    String input=br.readLine();
                    List<String> tokens = tokenize(input);
                    System.out.println("tokens: " + tokens);
                    List<String> postfix = toPostfix(tokens);
                    System.out.print("postfix: ");
                    for(String s: postfix) System.out.print(s + " ");
                    System.out.println();
                }
            }
    }
    

    【讨论】:

    • thnx...只是一个疑问 " Pattern p = Pattern.compile("\(|\)|[A-Za-z]+|\\d*\\.\\ d*|\\d+|\\S+?");"这样做....我知道它会产生一个 obj。模式的.什么是.compile.....做
    • 查看 Pattern 类的文档。 docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html 它从正则表达式创建一个模式。在这种情况下,它会查找“(”或“)”或字母序列或带有点的数字或整数或非空白字符序列。
    猜你喜欢
    • 2013-02-26
    • 2013-09-23
    • 2015-05-22
    • 2015-09-12
    • 2012-04-05
    • 2015-09-13
    • 2016-07-08
    • 2021-10-02
    • 2013-03-28
    相关资源
    最近更新 更多