Java 后缀计算器中的 StackOverFlowError

发布于 2024-08-24 06:10:46 字数 4925 浏览 8 评论 0原文

下面的类被另一个程序使用。当它被访问时,它会抛出 StackOverFlowError。这是我在大学必须做的一个项目的 Postfix 计算器的一部分。

任何帮助将不胜感激,提前谢谢您。我对 Java 很陌生,我不知道该怎么做。

代码:

import java.util.Queue;
import java.util.Stack;

public class MyPostfixMachine implements PostfixMachineInterface {

    MyMathOperations mmo = new MyMathOperations();
    MyPostfixMachine mpm = new MyPostfixMachine();

    public String evaluate(Queue q) {
        if (q.isEmpty()) {//if the input is empty, terminate the program
            System.exit(0);
        }
        if (q.size() == 1) {//if there is only one number in the queue, return it as the solution
            if (mpm.isParsableToDouble(String.valueOf(q.remove()))) {
                return String.valueOf(q.remove());
            }
        }
        Stack<String> finalxp = new Stack<String>();//create an empty stack
        if (mpm.isParsableToDouble(String.valueOf(q.remove()))) {//if first element of queue q is a number,push it into the stack
            finalxp.push(String.valueOf(q.remove()));
        } else {//depending on the operator perform the corresponding operations
            if (q.remove() == "+") {
                String str = String.valueOf(finalxp.pop());
                String str2 = String.valueOf(finalxp.pop());
                finalxp.push(mmo.addition(str, str2));
            }
            if (q.remove() == "-") {
                String str = String.valueOf(finalxp.pop());
                String str2 = String.valueOf(finalxp.pop());
                finalxp.push(mmo.substraction(str, str2));
            }
            if (q.remove() == "*") {
                String str = String.valueOf(finalxp.pop());
                String str2 = String.valueOf(finalxp.pop());
                finalxp.push(mmo.product(str, str2));
            }
            if (q.remove() == "/") {
                String str = String.valueOf(finalxp.pop());
                String str2 = String.valueOf(finalxp.pop());
                finalxp.push(mmo.division(str, str2));
            }
            if (q.remove() == "fibo") {
                String str = String.valueOf(finalxp.pop());
                finalxp.push(mmo.fibonacci(str));
            }
            if (q.remove() == "fac") {
                String str = String.valueOf(finalxp.pop());
                finalxp.push(mmo.factorial(str));
            }
            if (q.remove() == "han") {
                String str = String.valueOf(finalxp.pop());
                finalxp.push(mmo.hanoi(str));
            }
        }
        return String.valueOf(finalxp.pop());
    }

    public boolean isParsableToDouble(String candidate) {
        try {
            Double.parseDouble(candidate);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }
}





public class MyMathOperations implements MathOperationsInterface {

public String addition(String s1, String s2) {

    double A = Double.parseDouble(s1);
    double B = Double.parseDouble(s2);

    return String.valueOf((A + B));
}

public String substraction(String s1, String s2) {
    double A = Double.parseDouble(s1);
    double B = Double.parseDouble(s2);

    return String.valueOf((A - B));
}

public String product(String s1, String s2) {
    double A = Double.parseDouble(s1);
    double B = Double.parseDouble(s2);

    return String.valueOf((A * B));
}

public String division(String s1, String s2) {
    double A = Double.parseDouble(s1);
    double B = Double.parseDouble(s2);

    return String.valueOf((A / B));
}

public String fibonacci(String s) {
    int n = Integer.parseInt(s);
    return String.valueOf(fibo(n));
}

public int fibo(int f) {
    if (f < 0) {
        throw new IllegalArgumentException("Cannot apply Fibonacci method");
    } else if (f == 0) {
        return 0;
    } else if (f == 1) {
        return 1;
    } else {
        return fibo(f - 1) + fibo(f - 2);
    }

}

public String hanoi(String s) {
    int a = Integer.parseInt(s);
    int han = 0;
    if (a < 0) {
        throw new IllegalArgumentException("Not a valid integer");
    } else {
        han = (int) Math.pow(2, a) - 1;
    }
    return String.valueOf(han);
}

public String factorial(String s) {
    int a = Integer.parseInt(s);

    if (a < 0) {
        throw new IllegalArgumentException("Incorrect argument for factorial operatiion");
    }
    switch (a) {
        case 0:
        case 1:
            return String.valueOf(1);
        default:

            int res = a;
            while (true) {
                if (a == 1) {
                    break;
                }

                res *= --a;
            }
            return String.valueOf(res);
    }

}

private static double pDouble(String s) {
    double res = 0d;
    try {
        res = Double.parseDouble(s);
    } catch (NumberFormatException e) {
        System.exit(1);
    }

    return res;
}

}

The following class is used by another program. When it is accessed, it throws a StackOverFlowError. This is part of a Postfix Calculator I have to do as a project at my university.

Any help would be greatly appreciated, thank you in advance. I'm quite new at Java and I have no idea what to do.

CODE:

import java.util.Queue;
import java.util.Stack;

public class MyPostfixMachine implements PostfixMachineInterface {

    MyMathOperations mmo = new MyMathOperations();
    MyPostfixMachine mpm = new MyPostfixMachine();

    public String evaluate(Queue q) {
        if (q.isEmpty()) {//if the input is empty, terminate the program
            System.exit(0);
        }
        if (q.size() == 1) {//if there is only one number in the queue, return it as the solution
            if (mpm.isParsableToDouble(String.valueOf(q.remove()))) {
                return String.valueOf(q.remove());
            }
        }
        Stack<String> finalxp = new Stack<String>();//create an empty stack
        if (mpm.isParsableToDouble(String.valueOf(q.remove()))) {//if first element of queue q is a number,push it into the stack
            finalxp.push(String.valueOf(q.remove()));
        } else {//depending on the operator perform the corresponding operations
            if (q.remove() == "+") {
                String str = String.valueOf(finalxp.pop());
                String str2 = String.valueOf(finalxp.pop());
                finalxp.push(mmo.addition(str, str2));
            }
            if (q.remove() == "-") {
                String str = String.valueOf(finalxp.pop());
                String str2 = String.valueOf(finalxp.pop());
                finalxp.push(mmo.substraction(str, str2));
            }
            if (q.remove() == "*") {
                String str = String.valueOf(finalxp.pop());
                String str2 = String.valueOf(finalxp.pop());
                finalxp.push(mmo.product(str, str2));
            }
            if (q.remove() == "/") {
                String str = String.valueOf(finalxp.pop());
                String str2 = String.valueOf(finalxp.pop());
                finalxp.push(mmo.division(str, str2));
            }
            if (q.remove() == "fibo") {
                String str = String.valueOf(finalxp.pop());
                finalxp.push(mmo.fibonacci(str));
            }
            if (q.remove() == "fac") {
                String str = String.valueOf(finalxp.pop());
                finalxp.push(mmo.factorial(str));
            }
            if (q.remove() == "han") {
                String str = String.valueOf(finalxp.pop());
                finalxp.push(mmo.hanoi(str));
            }
        }
        return String.valueOf(finalxp.pop());
    }

    public boolean isParsableToDouble(String candidate) {
        try {
            Double.parseDouble(candidate);
            return true;
        } catch (NumberFormatException nfe) {
            return false;
        }
    }
}





public class MyMathOperations implements MathOperationsInterface {

public String addition(String s1, String s2) {

    double A = Double.parseDouble(s1);
    double B = Double.parseDouble(s2);

    return String.valueOf((A + B));
}

public String substraction(String s1, String s2) {
    double A = Double.parseDouble(s1);
    double B = Double.parseDouble(s2);

    return String.valueOf((A - B));
}

public String product(String s1, String s2) {
    double A = Double.parseDouble(s1);
    double B = Double.parseDouble(s2);

    return String.valueOf((A * B));
}

public String division(String s1, String s2) {
    double A = Double.parseDouble(s1);
    double B = Double.parseDouble(s2);

    return String.valueOf((A / B));
}

public String fibonacci(String s) {
    int n = Integer.parseInt(s);
    return String.valueOf(fibo(n));
}

public int fibo(int f) {
    if (f < 0) {
        throw new IllegalArgumentException("Cannot apply Fibonacci method");
    } else if (f == 0) {
        return 0;
    } else if (f == 1) {
        return 1;
    } else {
        return fibo(f - 1) + fibo(f - 2);
    }

}

public String hanoi(String s) {
    int a = Integer.parseInt(s);
    int han = 0;
    if (a < 0) {
        throw new IllegalArgumentException("Not a valid integer");
    } else {
        han = (int) Math.pow(2, a) - 1;
    }
    return String.valueOf(han);
}

public String factorial(String s) {
    int a = Integer.parseInt(s);

    if (a < 0) {
        throw new IllegalArgumentException("Incorrect argument for factorial operatiion");
    }
    switch (a) {
        case 0:
        case 1:
            return String.valueOf(1);
        default:

            int res = a;
            while (true) {
                if (a == 1) {
                    break;
                }

                res *= --a;
            }
            return String.valueOf(res);
    }

}

private static double pDouble(String s) {
    double res = 0d;
    try {
        res = Double.parseDouble(s);
    } catch (NumberFormatException e) {
        System.exit(1);
    }

    return res;
}

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

扬花落满肩 2024-08-31 06:10:46

问题是您的类MyPostfixMachine有一个私有字段MyPostfixMachine mpm,它是用新的MyPostfixMachine初始化的。由于这个新的 MyPostfixMachine 也有一个私有字段 MyPostfixMachine mpm ,它是用新的 MyPostfixMachine 初始化的......你明白了。 :) 这会永远持续下去(或者直到你的堆栈已满)。

这是有问题的代码:

public class MyPostfixMachine implements PostfixMachineInterface {

    MyMathOperations mmo = new MyMathOperations();
    MyPostfixMachine mpm = new MyPostfixMachine(); // problem is here

    // ...
}

我认为您可以简单地删除私有字段 mpm。只需调用当前实例上的方法即可。因此,

if (mpm.isParsableToDouble(String.valueOf(q.remove()))) {...}

您可以简单地编写:

if (isParsableToDouble(String.valueOf(q.remove()))) {...}

或 (等效但更明确): ,

if (this.isParsableToDouble(String.valueOf(q.remove()))) {...}

而不是: 无论如何,只需删除私有字段 mpm ,StackOverflowException 就会消失。

The problem is that your class MyPostfixMachine has a private field MyPostfixMachine mpm which is initialized with a new MyPostfixMachine. Since this new MyPostfixMachine also has a private field MyPostfixMachine mpm which is initialized with a new MyPostfixMachine... you get it. :) This goes on and on forever (or until your stack is full).

Here is the problematic piece of code:

public class MyPostfixMachine implements PostfixMachineInterface {

    MyMathOperations mmo = new MyMathOperations();
    MyPostfixMachine mpm = new MyPostfixMachine(); // problem is here

    // ...
}

I think you can simply remove the private field mpm. Just call the methods on the current instance. So instead of:

if (mpm.isParsableToDouble(String.valueOf(q.remove()))) {...}

you can simply write:

if (isParsableToDouble(String.valueOf(q.remove()))) {...}

or (equivallent but more explicit):

if (this.isParsableToDouble(String.valueOf(q.remove()))) {...}

Anyway, just remove the private field mpm and the StackOverflowException should be gone.

热风软妹 2024-08-31 06:10:46

我不确定你是如何得到 StackOverflowError 的(我在这段代码中没有看到任何循环或递归),但一个明确的问题是你过度使用了 Queue.remove() 。每次您在 if 子句中查看队列时,您都会删除第一个元素 - 我希望这段代码会抛出 NoSuchElementExceptions 。

更不用说所有的 EmptyStackException 了,你应该从空的 Stack 中弹出。

所以我想说......

  1. 当你应该调用 `peek()` 时,请退出调用 `remove()` 。
  2. 停止从空堆栈中弹出;您想从输入队列中提取这些值,是吗?
  3. 给您带来“StackOverFlowError”的问题在其他地方。 (除非我忽略了某些东西——总是有可能的!)寻找循环或递归调用。

I'm not sure how you're getting a StackOverflowError (I don't see any loops or recursion in this code), but one definite problem is your overuse of Queue.remove(). Every time you look at the queue in your if clauses, you're lopping-off the first element -- I'd expect this code to be barfing-out NoSuchElementExceptions.

To say nothing of all the EmptyStackExceptions you should be getting from popping from an empty Stack.

So I'd say....

  1. Quit calling `remove()` when you should be calling `peek()` instead.
  2. Quit popping from an empty stack; you want to be pulling those values from your input queue, yes?
  3. The problem giving you your `StackOverFlowError` is elsewhere. (Unless I'm overlooking something -- always possible!) Look for a loop or a recursive call.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文