java堆栈下溢 [英] java stack Underflow

查看:31
本文介绍了java堆栈下溢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在完成这项任务并在线程中不断收到异常"main" java.lang.RuntimeException: Stack Underflow at Stack.pop(Postfix.java:74)在 Postfix.eval(Postfix.java:221)at Postfix.main(Postfix.java:112)

im work this assignment and keep getting Exception in thread "main" java.lang.RuntimeException: Stack Underflow at Stack.pop(Postfix.java:74) at Postfix.eval(Postfix.java:221)at Postfix.main(Postfix.java:112)

不知道为什么我查看堆栈并正确写入,我看不出为什么它在 (3*4)/5 时弹出的问题

dont know why i look at the stack and write it correct , i cant see problem why it pop when (3*4)/5

import java.io.IOException;
class  CharStack
{
    private final int STACKSIZE= 80;
    private int top;
    private char[] items;

    public CharStack(){
          items = new char[STACKSIZE];
          top =-1;

    }

    public boolean empty() {

        if(top==-1){
               return true;
           }


               return false;

    }

    public char pop() {
         if(empty()){
             throw new RuntimeException("Stack Underflow");
          }
     return items[top--];

    }

    public void push(char symb) 
    {
        if(top == STACKSIZE -1) {
            throw new RuntimeException("Stack Overflow");
       }
      items[++top] =symb;


    }

    public char peek() {
           if(empty()){
                throw new RuntimeException("Stack Underflow");
            }
           return items[top];
    }
    }
class Stack {
    private final int STACKSIZE= 80;
    private int top;
    private double[] items;

    public Stack(){
          items = new double[STACKSIZE];
          top =-1;

    }
    public void push(double x) 
    {
        if(top == STACKSIZE -1) {
               throw new RuntimeException("Stack Overflow");
          }
         items[++top] =x;



    }

    public double pop(){
        if(empty()){
             System.out.print(top);
            throw new RuntimeException("Stack Underflow");
         }
    return items[top--];

   }

    public double peek()  {
           if(empty()){

                throw new RuntimeException("Stack Underflow");
            }
           return items[top];


    }
   boolean empty()
   {
       if(top==-1){
           return true;
       }

           return false;


   }
}
public class Postfix {

     public final static int MAXCOLS = 80;

    public static void main(String[] args) throws IOException {

        String infix, pfix;
        System.out.println("Enter a infix  String: ");
        infix = readString().trim();
        System.out.println("The original infix expr is:  " + infix);
        pfix = postfix(infix);
        System.out.println("The Postfix expr is:  " + pfix);
        System.out.println("The value is :  " + eval(pfix));
    } // end main


    public static boolean isOperand(char x) 
    {
        if(x == '+')
        {
            return false;
        }
        else if(x == '-')
        {
            return false;
        }
        else if (x == '*')
        {
            return false;
        }
        else if (x ==  '/')
        {
            return false;
        }
        else if ( x== '$')
        {
            return false;
        }

        return true;

    }


    public static int operPrecedence(char oper) 
    {
        if(oper == '+'||oper == '-' )       
        {
            return 1;
        }

        else if (oper == '*' || oper ==  '/')
        {
            return 2;
        }

        else if (oper == '$')
        {
            return 3;
        }
        return 0;

    }


    public static boolean precedence(char top, char symb) 
    {

        if ((top != '('||top != ')')&&symb == '(')
        {
            return false;
        }
        if (top == '(' && (symb != '('||symb != ')') )
        {
            return false;
        }

        else if((top != '('||top != ')')&&symb ==')' )
        {
            return true;
        }
         int opcode1, opcode2;
         opcode1 =operPrecedence(top) ;
         opcode2 =operPrecedence(symb) ;

        if(opcode1>=opcode2){
            return true;
        }
            return false;

        }


    public static String readString() throws IOException {
        char[] charArray = new char[80];
        int position = 0;
        char c;
        while ((c = (char) System.in.read()) != '\n') {
            charArray[position++] = c;

        }
        return String.copyValueOf(charArray, 0, position); // turns a character array into a string, starting between zero and position-1

    }// end read string

    public static double eval(String infix) {

        char c;
        int position;
        double opnd1, opnd2, value;
        Stack opndstk = new Stack();
        for (position = 0; position < infix.length(); position++) {
            c = infix.charAt(position);
            if (Character.isDigit(c)) // operand-convert the character represent  of  
            // the digit into double and push it into the
            // stack
            {
                opndstk.push((double) Character.digit(c, 10));
            } else {

                // operator
                opnd2 = opndstk.pop();
                opnd1 = opndstk.pop();
                value = oper(c, opnd1, opnd2);
                opndstk.push(value);
            } // else
        } // end for
        return opndstk.pop();
    }// end eval

    public static String postfix(String infix) {
        int position, outpos = 0;
        char symb;
        char[] postr = new char[MAXCOLS];
        CharStack opstk = new CharStack();
        for (position = 0; position < infix.length(); position++) {
            symb = infix.charAt(position);
            if (isOperand(symb)) {
                postr[outpos++] = symb;
            } else {
                while (!opstk.empty() && precedence(opstk.peek(), symb)) {
                    postr[outpos++] = opstk.pop();
                } // end while
                if (symb != ')') {
                    opstk.push(symb);
                } else {
                    opstk.pop();
                }
            } // end else

        } // end for
        while (!opstk.empty()) {
            postr[outpos++] = opstk.pop();
        }
        return String.copyValueOf(postr, 0, outpos);

    }// end pos

    public static double oper(char symb, double op1, double op2) {

        double value = 0;
        switch (symb) {
            case '+':
                value = op1 + op2;
                break;
            case '-':
                value = op1 - op2;
                break;
            case '*':
                value = op1 * op2;
                break;
            case '/':
                value = op1 / op2;
                break;
            case '$':
                value = Math.pow(op1, op2);
                break;
            default:
                throw new RuntimeException("illegal operator: " + symb);

        }// end switch
        return value;
    }// end oper

}

推荐答案

您遇到的至少部分问题是您的 isOperand 方法.字符 () 不是操作数,但是,当它们传递给这个方法时,它会返回 true.为了快速测试,我在方法的末尾添加了以下几行:

At least part of the problem you're having is your isOperand method. The characters ( and ) are not operands, however, when they are passed to this method, it would return true. For a quick test, I added the following lines to the end of the method:

else if (x == '(')
{
    return true;
}
else if (x == ')')
{
    return true;
}

您的示例输入 (3*4)/5) 运行成功.但是,这会破坏您的后缀输出,因为它将括号从后缀版本中删除,而是打印 34*5/,我猜您不想要.

And your example input, (3*4)/5) runs successfully. However, this breaks your postfix output, as it leaves the brackets out of the postfix version and instead prints 34*5/, which I am guessing you don't want.

然后,根据我收到的错误消息,我查看了您的 eval 方法,这是问题的来源:

Then, I looked at your eval method, which is where the problem is coming from, according to the error message I'm receiving:

Exception in thread "main" java.lang.RuntimeException: Stack Underflow
    at Stack.pop(Postfix.java:74)
    at Postfix.eval(Postfix.java:221)
    at Postfix.main(Postfix.java:112)

注意行 Postfix.java:221,它表示调用产生错误的方法的行.如果您在调用该行之前输出字符 c,您会注意到 c( 字符,这意味着您的 eval 方法正在将 ( 识别为运算符,并试图在其后弹出两个操作数,从而导致下溢.

Note the line Postfix.java:221, which indicates the line that called the method which created the error. If you output your character c right before that line is called, you'll notice that c is the ( character, which means your eval method is recognizing ( as an operator, and is attempting to pop two operands after it, causing your underflow.

通过一些 System.out.println() 调用并查看您的错误,可以很容易地确定所有这些.我会把实际的修复留给你,但至少你现在希望有一个前进的方向.

All of this is fairly simple to determine with some System.out.println() calls, and looking at your error. I'll leave the actual fixing to you, but at least you've hopefully got a direction to head in now.

这篇关于java堆栈下溢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆