在java中使用postix转换

时间:2016-03-10 10:45:07

标签: java class stack infix-notation

我有一个将中缀表达式转换为后缀的java类。我已经设法使类运行没有错误,但它没有给我正确的输出。输出结果为:

  

InToPost:将表达式从中缀转换为后缀...
[A,+,   B]
[A,+,B,*,C]
[A,+,B,*,C,+,D]
[(,A,+,B,) ,   *,C]
[(,A,+,B,),/,(,C, - ,D,)]
[(,(,A,+,B,),*, C, - ,(,D, - ,E,),)]
InToPost:发光后缀   表达式...
A B +
A B C * + A A B C * + D +
A B + C.   * A B + C D - /
A B + C * D E - -

但我的输出是:

  

InToPost:将表达式从中缀转换为后缀... [A,+,   B]
[A,+,B,*,C]
[A,+,B,*,C,+,D]
[(,A,+,B,) ,   *,C]
[(,A,+,B,),/,(,C, - ,D,)]
[(,(,A,+,B,),,C, - ,(,D, - ,E,),)]
InToPost:发出后缀表达式......   A + B
A + B
C
A + B * C + D
(A + B)* C
(A + B)/(CD)
  ((A + B)* C-(d-E))

转换方法如下:

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;
    }

全班代码是:

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();
    }
}

2 个答案:

答案 0 :(得分:1)

这是一种可能性。您可以分析此代码并在您的代码中找到错误。

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);
     }
   }
}

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

答案 1 :(得分:0)

您可以签出我的代码。在这里,后缀转换的后缀是通过遵循运算符的优先级和关联性的所有规则执行的。

一些转换规则是:

  1. 在到达操作数时打印它们。
  2. 如果堆栈为空或顶部带有左括号,则将传入的运算符压入堆栈。
  3. 如果传入符号为'(',则将其压入堆栈。
  4. 如果传入的符号是')',则弹出堆栈并在操作符单元左侧打印'(';遇到弹出的符号时也弹出'(',但不要将其添加到结果中。
  5. 如果传入符号的优先级高于堆栈顶部,则将其推入堆栈。
  6. 如果传入符号的优先级低于堆栈顶部的优先级,请弹出并打印顶部。然后针对新堆栈顶部测试传入运算符。
  7. 如果传入符号的优先级与堆栈顶部的优先级相等,请使用“关联性”规则。
  8. 关联性规则,如果关联性为L-R,则弹出并打印堆栈顶部并压入传入的运算符。
  9. 关联性规则,如果关联性为R-L,则将传入的运算符压入堆栈。
  10. 在表达式末尾,弹出并打印堆栈的所有运算符。

有关更多信息,请参见: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]));
        }
    }
}