简体   繁体   English

java中中缀到后缀的转换

[英]Infix to postfix conversion in java

I have a java class that converts infix expression to postfix.我有一个将中缀表达式转换为后缀的 java 类。 I have managed to make the class run without errors but it is not giving me the right output.我已经设法让课程运行没有错误,但它没有给我正确的输出。 The output is suppose to be in form :假设输出格式为:

InToPost: converting expressions from infix to postfix... InToPost:将表达式从中缀转换为后缀...
[A, +, B] [A、+、B]
[A, +, B, *, C] [A、+、B、*、C]
[A, +, B, *, C, +, D] [A、+、B、*、C、+、D]
[(, A, +, B, ), *, C] [(, A, +, B, ), *, C]
[(, A, +, B, ), /, (, C, -, D, )] [(, A, +, B, ), /, (, C, -, D, )]
[(, (, A, +, B, ), *, C, -, (, D, -, E, ), )] [(, (, A, +, B, ), *, C, -, (, D, -, E, ), )]
InToPost: emitting postfix expressions... InToPost:发出后缀表达式...
AB + AB +
ABC * + ABC * +
ABC * + D + ABC * + D +
AB + C * AB + C *
AB + CD - / AB + CD - /
AB + C * DE - - AB + C * DE - -

But my output is:但我的输出是:

InToPost: converting expressions from infix to postfix... [A, +, B] InToPost:将表达式从中缀转换为后缀... [A, +, B]
[A, +, B, *, C] [A、+、B、*、C]
[A, +, B, *, C, +, D] [A、+、B、*、C、+、D]
[(, A, +, B, ), *, C] [(, A, +, B, ), *, C]
[(, A, +, B, ), /, (, C, -, D, )] [(, A, +, B, ), /, (, C, -, D, )]
[(, (, A, +, B, ), , C, -, (, D, -, E, ), )] [(, (, A, +, B, ), , C, -, (, D, -, E, ), )]
InToPost: emitting postfix expressions... A+B InToPost:发出后缀表达式... A+B
A+B C A+B C
A+B*C+D A+B*C+D
(A+B)*C (A+B)*C
(A+B)/(CD) (A+B)/(CD)
((A+B)*C-(DE)) ((A+B)*C-(DE))

The convert method is as follows:转换方法如下:

private List<String> convert(List<String> tokens) {
        // YOUR IMPLEMENTATION HERE

        StackNode opstack = new StackNode();

        //List<Object> postfix = new ArrayList<Object>();

        //int sizeOfList=tokens.size();      
        String postfixString = " ";

        for (int index = 0; index < tokens.size(); ++index) {
            String chValue = tokens.get(index);
            if (chValue == "(") {
                opstack.push("(");
            } else if (chValue == ")") {
                String oper = String.valueOf(opstack.top());
                while (!(oper.equals("(")) && !(opstack.empty())) {
                    postfixString += oper;
                    opstack.pop();
                    oper = String.valueOf(opstack.top());
                }
                opstack.pop();
            } else if (chValue == "+" || chValue == "-") {
                //Stack is empty
                if (opstack.empty()) {
                    opstack.push(chValue);
                    //current Stack is not empty
                } else {
                    String oper = String.valueOf(opstack.top());
                    while (!(opstack.empty() || oper.equals(new String("(")) || oper.equals(new String(")")))) {
                        opstack.pop();
                        postfixString += oper;
                    }
                    opstack.push(chValue);
                }
            } else if (chValue == "*" || chValue == "/") {
                if (opstack.empty()) {
                    opstack.push(chValue);
                } else {
                    String oper = String.valueOf(opstack.top());
                    while (!oper.equals(new String("+")) && !oper.equals(new String("-")) && !opstack.empty()) {
                        opstack.pop();
                        postfixString += oper;
                    }
                    opstack.push(chValue);
                }
            } else {
                postfixString += chValue;
            }
        }
        while (!opstack.empty()) {
            String oper = String.valueOf(opstack.top());
            if (!oper.equals(new String("("))) {
                opstack.pop();
                postfixString += oper;
            }
        }

String[] strValues = postfixString.split(",");        
        ArrayList<String> postfix = new ArrayList<String>(Arrays.asList(strValues));
       return postfix;
    }

The whole class code is:全班代码为:

package sr.stu;
import sr.cs.Stack;
import sr.stu.StackNode;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

/**
 * A program that converts an infix expression to postfix.<br>
 * <br>
 *  Usage: java InToPost filename<br>
 * <br>
 * For example, prog1.in, containing infix expressions (one per line):<br>
 * <br>
 *  A + B<br>
 *  A + B * C<br>
 *  A + B * C + D<br>
 *  ( A + B ) * C<br>
 *  ( A + B ) / ( C - D )<br>
 *  ( ( A + B ) * C - ( D - E ) )<br>
 * <br>
 * When run: java InToPost prog1.in:<br>
 * <br>
 *  InToPost: converting expressions from infix to postfix...<br>
 *  [A, +, B]<br>
 *  [A, +, B, *, C]<br>
 *  [A, +, B, *, C, +, D]<br>
 *  [(, A, +, B, ), *, C]<br>
 *  [(, A, +, B, ), /, (, C, -, D, )]<br>
 *  [(, (, A, +, B, ), *, C, -, (, D, -, E, ), )]<br>
 *  InToPost: emitting postfix expressions...<br>
 *  A B +<br>
 *  A B C * +<br>
 *  A B C * + D +<br>
 *  A B + C *<br>
 *  A B + C D - /<br>
 *  A B + C * D E - -<br>
 * <br>

 */
public class InToPost{
    /** The add operator */
    public final static String ADD = "+";
    /** The subtract operator */
    public final static String SUBTRACT = "-";
    /** The multiply operator */
    public final static String MULTIPLY = "*";
    /** The divide operator */
    public final static String DIVIDE = "/";
    /** The open parentheses operator */
    public final static String OPEN_PAREN = "(";
    /** The close parentheses operator */
    public final static String CLOSE_PAREN = ")";

    /** The list of converted postfix expressions */
    private List<List<String>> expressions;
    /** The name of the infix source file */
    private String srcFile;
    /** A dictionary that maps operators (strings) to their precedence level
     * (integer) from highest (3) to lowest (1):
     *      *, /: 3
     *      +, -: 2
     *      (: 1
     */
    private Map<String, Integer> precedence;

    /**
     * Create a new IntoPost object.
     * @param filename The name of the infix source file
     */
    public InToPost(String filename) {
        this.expressions = new LinkedList<>();
        this.srcFile = filename;

        /** populate the precedence map */
        this.precedence = new HashMap<>();
        this.precedence.put(MULTIPLY, 3);
        this.precedence.put(DIVIDE, 3);
        this.precedence.put(ADD, 2);
        this.precedence.put(SUBTRACT, 2);
        this.precedence.put(OPEN_PAREN, 1);
    }

    /**
     * A private utility method that can be used by the private convert
     * method when dealing with the precedence of math operators on
     * the stack.  Indicates whether the top token on stack has greater
     * than or equal precedence than the current token.  For example:
     *  greaterEqualPrecedence("+", "*") -> false
     *  greaterEqualPrecedence("*", "+") -> true
     *  greaterEqualPrecedence("+", "-") -> true
     *  greaterEqualPrecedence("(", "/") -> false
     *
     * @param token the current math token, e.g. "+"
     * @param top the top token to compare to, e.g. "*"
     * @return true if top has greater than or equal precedence than
     *  token, false otherwise
     */
    private boolean greaterEqualPrecedence(String top, String token) {
        return this.precedence.get(top) >= this.precedence.get(token);
    }

    /**
     * A private helper conversion function that takes a list of tokens
     * (strings) in infix form and converts them to a list of tokens
     * (strings) in postfix form.
     *
     *  For example:
     *      tokens = ["A", "+", "B"]
     *      postfix = ["A", "B", "+"]
     *
     *  Note, this method must use either StackList<T> or StackNode<T>
     *  to represent the stack structure in the conversion algorithm.
     *
     * @param tokens the list of tokens (strings) in infix form
     * @return a new list of tokens (strings) in postfix form
     */
    private List<String> convert(List<String> tokens) {
        // YOUR IMPLEMENTATION HERE

        StackNode opstack = new StackNode();

        //List<Object> postfix = new ArrayList<Object>();

        //int sizeOfList=tokens.size();      
        String postfixString = " ";

        for (int index = 0; index < tokens.size(); ++index) {
            String chValue = tokens.get(index);
            if (chValue == "(") {
                opstack.push("(");
            } else if (chValue == ")") {
                String oper = String.valueOf(opstack.top());
                while (!(oper.equals("(")) && !(opstack.empty())) {
                    postfixString += oper;
                    opstack.pop();
                    oper = String.valueOf(opstack.top());
                }
                opstack.pop();
            } else if (chValue == "+" || chValue == "-") {
                //Stack is empty
                if (opstack.empty()) {
                    opstack.push(chValue);
                    //current Stack is not empty
                } else {
                    String oper = String.valueOf(opstack.top());
                    while (!(opstack.empty() || oper.equals(new String("(")) || oper.equals(new String(")")))) {
                        opstack.pop();
                        postfixString += oper;
                    }
                    opstack.push(chValue);
                }
            } else if (chValue == "*" || chValue == "/") {
                if (opstack.empty()) {
                    opstack.push(chValue);
                } else {
                    String oper = String.valueOf(opstack.top());
                    while (!oper.equals(new String("+")) && !oper.equals(new String("-")) && !opstack.empty()) {
                        opstack.pop();
                        postfixString += oper;
                    }
                    opstack.push(chValue);
                }
            } else {
                postfixString += chValue;
            }
        }
        while (!opstack.empty()) {
            String oper = String.valueOf(opstack.top());
            if (!oper.equals(new String("("))) {
                opstack.pop();
                postfixString += oper;
            }
        }

String[] strValues = postfixString.split(",");        
        ArrayList<String> postfix = new ArrayList<String>(Arrays.asList(strValues));
       return postfix;
    }

    /**
     * The public conversion function that converts all infix expressions
     * in the source file (one per line), into postfix expressions.
     * @throws FileNotFoundException if the file is not found
     */
    public void convert() throws FileNotFoundException {
        Scanner in = new Scanner(new File(this.srcFile));
        while (in.hasNext()) {
            // convert the line into a list of strings, e.g.
            //      line = "A B +"
            //      tokens = ["A", "B", "+"]
            List<String> tokens = Arrays.asList(in.nextLine().split(" "));
            // if the line isn't empty, convert it to postfix and add it to
            // the list of expressions
            if (tokens.size() > 0) {
                System.out.println(tokens);
                this.expressions.add(convert(tokens));
            }
        }
    }

    /**
     * Display the converted postfix expressions.
     */
    public void emit() {
        for (List<String> expression : this.expressions) {
            for (String token : expression) {
                System.out.print(token + " ");
            }
            System.out.println();
        }
    }

    /**
     * The main program takes the source file of infix expressions, converts
     * them to postfix, and displays them.
     * @param args command line arguments
     * @throws FileNotFoundException if the source file is not found
     */
    public static void main(String[] args) throws FileNotFoundException {
        if (args.length != 1) {
            System.out.println("Usage: java InToPost.py source-file.in");
            return;
        }

        InToPost inToPost = new InToPost(args[0]);
        System.out.println("InToPost: converting expressions from infix to postfix...");
        inToPost.convert();
        System.out.println("InToPost: emitting postfix expressions...");
        inToPost.emit();
    }
}

Here is a possibility.这是一种可能性。 You could analyze this code and find the error(s) in yours.您可以分析此代码并在您的代码中找到错误。

public class InToPost {
   private Stack theStack;
   private String input;
   private String output = "";
   public InToPost(String in) {
      input = in;
      int stackSize = input.length();
      theStack = new Stack(stackSize);
   }
   public String doTrans() {
      for (int j = 0; j < input.length(); j++) {
         char ch = input.charAt(j);
         switch (ch) {
            case '+': 
            case '-':
            gotOper(ch, 1); 
            break; 
            case '*': 
            case '/':
            gotOper(ch, 2); 
            break; 
            case '(': 
            theStack.push(ch);
            break;
            case ')': 
            gotParen(ch); 
            break;
            default: 
            output = output + ch; 
            break;
         }
      }
      while (!theStack.isEmpty()) {
         output = output + theStack.pop();
      }
      System.out.println(output);
      return output; 
   }
   public void gotOper(char opThis, int prec1) {
      while (!theStack.isEmpty()) {
         char opTop = theStack.pop();
         if (opTop == '(') {
            theStack.push(opTop);
            break;
         }
         else {
            int prec2;
            if (opTop == '+' || opTop == '-')
            prec2 = 1;
            else
            prec2 = 2;
            if (prec2 < prec1) { 
               theStack.push(opTop);
               break;
            }
            else
            output = output + opTop;
         }
      }
      theStack.push(opThis);
   }
   public void gotParen(char ch){ 
      while (!theStack.isEmpty()) {
         char chx = theStack.pop();
         if (chx == '(') 
         break; 
         else
         output = output + chx; 
      }
   }
   public static void main(String[] args) 
   throws IOException {
      String input = "1+2*4/5-7+3/6";
      String output;
      InToPost theTrans = new InToPost(input);
      output = theTrans.doTrans(); 
      System.out.println("Postfix is " + output + '\n');
   }
   class Stack {
      private int maxSize;
      private char[] stackArray;
      private int top;
      public Stack(int max) {
         maxSize = max;
         stackArray = new char[maxSize];
         top = -1;
      }
      public void push(char j) {
         stackArray[++top] = j;
      }
      public char pop() {
         return stackArray[top--];
      }
      public char peek() {
         return stackArray[top];
      }
      public boolean isEmpty() {
         return (top == -1);
     }
   }
}

Source: http://www.tutorialspoint.com/javaexamples/data_intopost.htm来源: http : //www.tutorialspoint.com/javaexamples/data_intopost.htm

you can checkout my code.你可以签出我的代码。 Here, infix to postfix conversion is performed by following all rules of Precedence and Associativity of operators.在这里,中缀到后缀的转换是通过遵循运算符的所有优先级和结合性规则来执行的。

Some rules for conversion are:一些转换规则是:

  1. Print operands as they arrive.在操作数到达时打印它们。
  2. If stack is empty or contains a left parenthesis on top, push the incoming operator on stack.如果堆栈为空或顶部包含左括号,则将传入的运算符压入堆栈。
  3. If incoming symbol is '(' push it onto the stack.如果传入符号是 '(' 将其压入堆栈。
  4. If the incoming symbol is ')' pop the stack and print the operators unit left '(' is encountered; pop '(' as well but do not add it to result.如果传入符号是 ')' 弹出堆栈并打印运算符单元 left '(' 遇到; pop '(' 以及但不要将其添加到结果中。
  5. If the incoming symbol has higher precedence than the top of stack, push it onto the stack.如果传入符号的优先级高于堆栈顶部,则将其压入堆栈。
  6. If the incoming symbol has lower precedence than the top of the stack, pop and print the top.Then test the incoming operator against the new top of stack.如果传入符号的优先级低于堆栈顶部,则弹出并打印顶部。然后针对新的堆栈顶部测试传入运算符。
  7. If the incoming symbol has equal precedence with the top of the stack, use Associativity rule.如果传入符号与堆栈顶部具有相同的优先级,则使用关联规则。
  8. Associativity rule, If associativity is LR, then pop and print the top of stack and push the incoming operator.结合性规则,如果结合性是 LR,则弹出并打印栈顶并压入传入的运算符。
  9. Associativity rule, If associativity is RL, then push the incoming operator on to stack.结合性规则,如果结合性是 RL,则将传入的运算符压入堆栈。
  10. At the end of expression, pop and print all operator of stack.在表达式结束时,弹出并打印堆栈的所有运算符。

For more info refer: Coding-Problems有关更多信息,请参阅:编码问题

package com.stack.problems;

import java.util.Arrays;
import java.util.List;
import java.util.Stack;

public class InfixToPostfixConversionUsingStack {

    static int precedence(Character ch) {

        switch (ch) {
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
                return 2;
            case '^':
                return 3;

        }
        return -1;
    }

    static boolean associativityForEqualPrecedence(char ch1, char ch2) {

        /*  Here, true represent L-R associativity and vice-versa.
         * */
        List<Character> charList = Arrays.asList('+', '-', '*', '/');
        return charList.contains(ch1) || charList.contains(ch2);    //Rule 8,9
    }

    private static String infixToPostfix(String exp) {

        if (exp == null || exp.isEmpty())
            return exp;
        Stack<Character> stack = new Stack<>();
        StringBuilder result = new StringBuilder();

        for (int index = 0; index < exp.length(); index++) {
            char ch = exp.charAt(index);
            if (Character.isLetterOrDigit(ch)) {
                result.append(ch);      //Rule 1
            } else if (ch == '(') {     //Rule 3
                stack.push(ch);
            } else if (ch == ')') {     //Rule 4
                while (!stack.isEmpty() && stack.peek() != '(') {
                    result.append(stack.pop());
                }
                if (!stack.isEmpty())
                    stack.pop();
                else { //For invalid expression...
                    System.out.println("Mismatched parenthesis....");
                    return null;
                }
            } else if (!stack.isEmpty()) {
                if (precedence(ch) > precedence(stack.peek())) {        //Rule 5
                    stack.push(ch);
                } else if (precedence(ch) < precedence(stack.peek())) {     //Rule 6

                    while (!stack.isEmpty() && precedence(ch) <= precedence(stack.peek())) {
                        result.append(stack.pop());
                    }
                    stack.push(ch);
                } else {        //Rule 7
                    //Here operators are having equal precedence therefore associativity rules are applied...
                    if (associativityForEqualPrecedence(ch, stack.peek())) {
                        result.append(stack.pop());
                    }
                    stack.push(ch);
                }
            } else if (stack.isEmpty() || stack.peek() == '(') {        //Rule 2
                stack.push(ch);
            }
        }
        //For handling invalid expression...
        if (!stack.isEmpty() && stack.search('(') != -1) {
            System.out.println("Mismatched parenthesis...");
            return null;
        }
        if (!stack.isEmpty()) {     //Rule 10
            while (!stack.isEmpty()) {
                result.append(stack.pop());
            }
        }
        return result.toString();
    }

    public static void main(String[] args) {

        String[] exprArray = {
                "K+L-M*N+(O^P)*W/U/V*T+Q^J^A",
                "a+b*(c^d-e)^(f+g*h)-i",
                "((a+b-c)*d^e^f)/g",
                "1+2+3*5+(6+7)+8",
                "((a-b)/c)",
                "a*b-a*b+a*b",
                "(a*b"};

        for (int index = 0; index < exprArray.length; index++) {
            System.out.println("Infix Expression: " + exprArray[index]);
            System.out.println("Postfix Expression: " + infixToPostfix(exprArray[index]));
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM