微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

后缀运算符与 convertInfixToPostfix Java 类无序

如何解决后缀运算符与 convertInfixToPostfix Java 类无序

所以我用 Java 编写了一个有效的 infixToPostifxConverter 类,它正确地转换了以下表达式: 中缀:6 + 2 * 5 -8 / 4 正确的后缀:6 2 5 * + 8 4 / - 中缀:6 % 2 ^ 5 -8 / 4 * 5 正确的后缀:6 2 5 ^% 8 4 / 5* -

但我已经使用 switch 语句实现了优先级方法,根据传递给它的运算符类型返回 1、2 或 3。如果operator1 的优先级低于operator2,我实际上需要编写返回true 的方法。否则,它应该返回 false。

但是当我重构以返回 true 或 false 时,我的后缀表达式不再正确并且以错误的顺序返回操作数。查看我在 convertToPostfix 方法标记“我认为问题在这里”的位置。我无法弄清楚我做错了什么?任何见解将不胜感激!

导入 java.util.Scanner; 公共类 InfixToPostfixConverter {

public Stack<Character> stack = new Stack<>();

public static void main(String[] args) { // main method

    InfixToPostfixConverter obj = new InfixToPostfixConverter(); // class object

    int cont = 0; // create variable to control pre-test loop
    Scanner sc = new Scanner(system.in); // create object to capture input

    while (cont != -1) {
        System.out.println("Enter expression to convert (no spaces!): ");
        //get user input infix expression
        StringBuffer infix = new StringBuffer();
        infix.append(sc.next());
        //output user input as postfix expression
        System.out.println("Postfix expression is:" + obj.convertToPostfix(infix));

        System.out.println("Enter -1 to quit. Else enter any single digit number to continue: ");
        cont = sc.nextInt(); // continue looping until user exits program

    };
}
//***************************************************************
//
//  Method:       convertToPostfix() method
//
//  Description:  takes the infix StringBuffer expression as input
//                  and returns converted postfix expression as result
//
//  Parameters:   StringBuffer infix
//
//  Returns:     StringBuffer postfix
//**************************************************************
public StringBuffer convertToPostfix(StringBuffer infix) {

    StringBuffer postfix = new StringBuffer(""); // variable to store converted postfix expression
    InfixToPostfixConverter obj = new InfixToPostfixConverter(); // class object

    for (int i = 0; i < infix.length(); i++) { // while there is input to read

        char c = infix.charat(i);

        // if scanned character is operand...
        if (Character.isLetterOrDigit(c))
            postfix.append(c); // ...add to output

        // if scanned character is '('...
        else if (c == '(')
            stack.push(c); // ...push onto stack

        else if (c == ')')
        // push all input back to (
        {
            while (!stack.isEmpty() && stack.peek() != '(') {
                postfix.append(stack.pop()); // add to output
            }
            stack.pop(); // remove '('
        }
        else // print operators occurring before which have a higher precedence
        {
            while (!stack.isEmpty() && obj.isOperator(c) && **obj.precedence(c,stack.peek()))** // I THINK PROBLEM IS HERE
            {
                postfix.append(stack.pop()); // add to output
            }
            stack.push(c); // push onto stack
        }
    }
    while (!(stack.isEmpty())) // stack is not empty...
    {
        postfix.append(stack.pop()); // ...add to output
    }
    return postfix;
}
//***************************************************************
//
//  Method:       precedence() method
//
//  Description:  determines whether
//              the precedence of operator1 (from the infix expression)
//              is less than,equal to or greater than,//              that of operator2 (from the stack)
//
//  Parameters:   char x
//
//  Returns:     true if operator1 has a precedence lower than that of operator2
//                  else,returns false
//**************************************************************
public boolean precedence(char operator1,char operator2)
{
    int op1Precedence = 0;
    int op2Precedence = 0;

    //assign operator1 precedence an integer value from 1-3
    if(operator1 == '+' || operator1 == '-')
        op1Precedence = 1;
    else if(operator1 == '*' || operator1 == '/' || operator1 == '%')
        op1Precedence = 2;
    else if(operator1 == '^')
        op1Precedence = 3;

    //assign operator2 precedence an integer value from 1-3
    if(operator2 == '+' || operator2 == '-')
        op2Precedence = 1;
    else if(operator2 == '*' || operator2 == '/' || operator2 == '%')
        op2Precedence = 2;
    else if(operator2 == '^')
        op2Precedence = 3;

    //compare precedence of operator1 and operator2
    if(op1Precedence < op2Precedence)
        return true;
    else
        return false;
}
//***************************************************************
//
//  Method:       isOperator() method
//
//  Description:  determines if c is an operator
//
//  Parameters:   char c
//
//  Returns:     true if c is an operator
//                  else,returns false
//**************************************************************
public boolean isOperator(char c)
{
    // if c is operator...
    if( c == '+' || c == '-' || c == '*' || c == '/' || c == '^' || c == '%')
        return true; // return true
    else
        return false;
}

}

解决方法

试试这个。

static final Map<Integer,Integer> PRIORITY = Map.of(
    (int)'+',1,(int)'-',(int)'*',2,(int)'/',(int)'%',(int)'^',3);

static String convertToPostfix(String infix) {
    StringBuilder postfix = new StringBuilder();
    new Object() {
        int index = 0;
        int ch = get();
        int token;

        int get() { return ch = index < infix.length() ? infix.charAt(index++) : -1; }
        void put(int... chars) { for (int c : chars) postfix.append((char)c); }
        void spaces() { while (Character.isWhitespace(ch)) get(); }

        boolean match(int... expects) {
            spaces();
            for (int e : expects)
                if (ch == e) {
                    token = ch;
                    get();
                    return true;
                }
            return false;
        }

        void number() {
            if (ch == '-') {
                put(ch); get();
                if (!Character.isDigit(ch))
                    throw new RuntimeException("digits expected");
            }
            do {
                put(ch); get();
            } while (Character.isDigit(ch));
        }

        void factor() {
            if (match('(')) {
                expression();
                if (!match(')'))
                    throw new RuntimeException("')' expected");
            } else if (ch == '-' || Character.isDigit(ch))
                number();
            else
                throw new RuntimeException("unknown char '" + (char) ch + "'");
        }

        void expression() {
            Deque<Integer> stack = new LinkedList<>();
            factor();
            while (match('+','-','*','/','%','^')) {
                int op = token;
                int p = PRIORITY.get(op);
                while (!stack.isEmpty() && p <= PRIORITY.get(stack.peek()))
                    put(' ',stack.pop());
                stack.push(op);
                put(' ');
                factor();
            }
            while (!stack.isEmpty())
                put(' ',stack.pop());
        }
    }.expression();
    return postfix.toString();
}

System.out.println(convertToPostfix("6 + 2 * 5 - 8 / 4"));
System.out.println(convertToPostfix("6 % 2 ^ 5 - 8 / 4 * 5"));
System.out.println(convertToPostfix("654 + 21 * (54 - 87) / 4"));

输出:

6 2 5 * + 8 4 / -
6 2 5 ^ % 8 4 / 5 * -
654 21 54 87 - * 4 / +

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。