1

これが、データ構造クラス用に作成する必要のあるJavaクラスです。これが変換を行うための最良の方法とはほど遠いことを私は知っていますが、それは彼がクラスで与えた擬似コードから外れており、そのために彼が探しているものです。彼が私たち自身で理解するために残した唯一のことは、アルゴリズムが括弧をどのように認識するかということでした。これらを使用せずに式を入力すると、プログラムは正常に実行されますが、括弧を追加するとプログラムは実行されません。具体的には、デバッグの結果、閉じ括弧がこれを実行することがわかりました")"。メソッドの実際の括弧部分がどこにあるかコメントでマークしました。助けてくれてありがとう!

public class InToPost {
    private Stack theStack;
    private String infix;
    private String postfix = "";

    public InToPost(String in) {
        infix = in;
        int stackSize = infix.length();
        theStack = new Stack(stackSize);
    }

    public String convert(){
        for (int i = 0; i < infix.length(); i++) {
            char ch = infix.charAt(i);
            if ((ch == '0') || (ch == '1') || (ch == '2') || (ch == '3') || (ch == '4') ||
                (ch == '5') || (ch == '6') || (ch == '7') || (ch == '8') || (ch == '9')) {
                postfix = postfix + ch;
            }
            //check for parenthesis
            else if (ch == ')'){
                while (theStack.topStk() != '('){
                    int topStk = theStack.pop();
                    postfix = postfix + topStk;
                }
                theStack.pop();
            } else {
                while ((theStack.isEmpty() == false)&&(prcd(theStack.topStk(),ch) == true)){
                    char topSymb = theStack.pop();
                    postfix = postfix + topSymb;
                }
                theStack.push(ch);
            }
        }
        while(theStack.isEmpty() == false){
            char topSymb = theStack.pop();
            postfix = postfix + topSymb;
        }
        return postfix;
    }

    public boolean prcd(char one, char two){
        int onePrcd = 0;
        int twoPrcd = 0;
        if ((one == '+') || (one == '-')){
            onePrcd = 1;
        }
        if ((two == '+') || (two == '-')){
            twoPrcd = 1;
        }
        if ((one == '*') || (one == '/')){
            onePrcd = 2;
        }
        if ((two == '*') || (two == '/')){
            twoPrcd = 2;
        }
        if (one == '$') {
            onePrcd = 3;
        }
        if (two == '$') {
            twoPrcd = 3;
        }
        if (one == '(') {
            onePrcd = 4;
        }
        if (two == '('){
            twoPrcd = 4;
        }
        if (onePrcd >= twoPrcd){
            return true;
        } else {
            return false;
        }
    }
    public static void main(String[] args){
        String input = "(2+3)*4";
        String output;
        InToPost theTrans = new InToPost(input);
        output = theTrans.convert(); 
        System.out.println("Postfix is " + output + '\n');
    }  
}
4

1 に答える 1

2

これは楽しいエクササイズでした。あなたはかなり近づいていましたが、ここにはいくつかのバグがあります. コードをデバッグして、少しいじる必要がありました。

  1. @SL Barth が述べたように、このwhile (theStack.topStk() != '('){行はスタック アンダーフローを引き起こす可能性があります。これを次のように変更する必要があります。

    while (!theStack.isEmpty() && theStack.topStk() != '('){

  2. theStack.pop();また、その下の権利を保護する必要があります。

    if (!theStack.isEmpty()) {
        theStack.pop();
    }
    
  3. '('スタックの一番上から優先度をチェックする場合、出力に文字を入れるべきではありません:

    if (topSymb != '(') {
        postfix = postfix + topSymb;
    }
    
  4. しかし、キッカーintのバグは、を閉じているときにスタックから にアンロードしている こと')'です。:-)int topStk = theStack.pop();+43

いくつかのスタイル ポイント:

  • 前述のように、使用Character.isDigit(ch)
  • 多くの文字列を作成する代わりに、 a を使用する必要StringBuilder()があります。[戦慄]postfix.append(ch)postfix + ch
  • スコープを縮小するために、postfixフィールドをメソッドに対してローカルにします。convert()
  • == falseまたはと言うのは悪い形と見なされます== true。をドロップして、false== trueの文字を使用するだけです。!(!theStack.isEmpty()) && prcd(theStack.topStk(),ch)
  • charToPrecedence(char)スイッチを使用して各文字の値を返す を作成します。よりクリーンなコード。

    public boolean precident(char one, char two) {
        return (charToPrcd(one) >= charToPrcd(two));
    }
    private int charToPrcd(char ch) {
        switch (ch) {
            case '+' : case '-' : return 1;
            case '*' : case '/' : return 2;
            case '$' : return 3;
            case '(' : return 4;
            default : return 0;
        }
    }
    
于 2011-10-06T16:42:30.933 に答える