4

この EmptyStackException は引き続きポップアップします。明らかに、私のスタックには何もありませんが、ユーザーが入力した最初の要素です。ただし、コードのどこに欠陥があるのか​​ わかりません。(多くのスポット)しかし、このエラーを修正する必要があります。

import java.util.*;

public class stacks2 {

public static void main (String []args){
System.out.printf("Enter a math equation in reverse polish notation:\n");

//Create stack of Strings
Stack<String> rpnStack = new Stack<String>();
//Create Scanner 
Scanner input = new Scanner(System.in);
//String in = input.next();

while(input != null) {
    String in = input.next();
        // Tokenize string based on spaces.
        StringTokenizer st = new StringTokenizer(in, " ", true);
            while (st.hasMoreTokens()) {
             rpnStack.push(st.nextToken());
         }
    //Send stack to Calculation Method
    calculate(rpnStack);
     }
}

public static void calculate(Stack<String> stack) {
    // Base case: stack is empty => Error, or finished
    if (!stack.isEmpty())
      // throw new StackUnderflowException("Empty Stack");

    // Base case: stack has 1 element, which is the answer => finished
    if (stack.size() == 1)
        System.out.printf("Finished, Answer: %s\n",stack.peek());

    // Recursive case: stack more elements on it.
    if (stack.size() > 1){
        String temp1 = stack.peek();
        stack.pop();
        String temp2 = stack.peek();
        stack.pop();
        String temp3 = stack.peek();
        stack.pop();


            if (temp3.equals("+")){
            float resultant = Float.parseFloat(temp1) + Float.parseFloat(temp2);
            stack.push(String.valueOf(resultant));
            //System.out.println(resultant);
            calculate(stack);
            }

            if (temp3.equals("-")){
            float resultant = Float.parseFloat(temp1) - Float.parseFloat(temp2);
            stack.push(String.valueOf(resultant)); 
            //System.out.println(resultant);
            calculate(stack);
            }

            else if (temp3.equals("*")){
            float resultant = Float.parseFloat(temp1) * Float.parseFloat(temp2);
            stack.push(String.valueOf(resultant)); 
            //System.out.println(resultant);
            calculate(stack);
            }

            else if (temp3.equals("/")){
            float resultant = Float.parseFloat(temp1) / Float.parseFloat(temp2);
            stack.push(String.valueOf(resultant)); 
            //System.out.println(resultant);
            calculate(stack);
            }

            else{
            System.out.printf("Something severely has gone wrong.");
            }
        }  
    }
}

入力とエラー:

:~ Home$ java stacks2
Enter a math equation in reverse polish notation:
4 5 * 6 -
Finished, Answer: 4
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:85)
at stacks2.calculate(stacks2.java:41)
at stacks2.main(stacks2.java:22)

明らかに、これは最初の要素のみを取得しているため、17 の while ループが原因であると思われます。洞察はありますか?

4

3 に答える 3

5

String in = input.next();あなたに1つの単語を読み、それからあなたはその単語をトークン化しようとしています。おそらくあなたは意味しましたString in = input.nextLine();

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Scanner.html#next()http://docs.oracle.com/javase/1.5.0/docs/api _ /java/util/Scanner.html#nextLine()


また、コードにはこれらの2行が含まれています。

if (!stack.isEmpty())
  // throw new StackUnderflowException("Empty Stack");

これは明らかに間違っています。中括弧がないと、ifは次のステートメントに影響します。コメントではありません-もしそうなら次のようになります。

これ:

if (!stack.isEmpty())
// throw new StackUnderflowException("Empty Stack");

// Base case: stack has 1 element, which is the answer => finished
if (stack.size() == 1)
    System.out.printf("Finished, Answer: %s\n",stack.peek());

これと同等です:

if (!stack.isEmpty())
    if (stack.size() == 1)
        System.out.printf("Finished, Answer: %s\n",stack.peek());

この:

if (!stack.isEmpty() && stack.size() == 1){
    System.out.printf("Finished, Answer: %s\n",stack.peek());
}

道徳:常に中括弧を使用し、ifアサーションをコメントアウトしないでください。アサーションをコメントアウトする場合でも、半分ではなく完全にコメント化してください。特に、残りの半分が括弧で囲まれていない場合はそうです。


第三に、あなたの論理には欠陥があります。これをして:

すべてのシンボルをスタックにプッシュしてから、上位3つをポップし、それらを演算子と2つの数字と見なします。代わりにキューを使用する場合、これは一部の入力で機能します。

4 5 * 6 -

あなたの論理によれば、これはポップ* 6 -してクラッシュします。キューを使用する場合、この場合は機能します

4 5 * 6 - 
20 6 -
14

しかし、この場合はそうではありません。

(1+1)*(1+1)
express as RPN
1 1 + 1 1 + *
2 1 1 + *

次に、211をポップしてクラッシュします。

代わりに、あなたがすべきこと:

Read the input. For each symbol:
  if it is a number,
    push it on the stack.
  else,
    pop two numbers from the stack,
    perform the operation and
     push the result.
于 2012-10-25T07:10:54.933 に答える
0

スタックは LIFO、つまり「後入れ先出し」です。したがって、入力シーケンスが4 5 * 6 -あり、これを行う場合:

rpnStack.push(st.nextToken());

最初にポップするのは「-」、2 番目は「6」、3 番目は「*」です。これはあなたが期待するものですか?

また、代わりに:

String temp1 = stack.peek();
stack.pop();

できるよ:

String temp1 = stack.pop();
于 2012-10-25T07:15:41.630 に答える