Java Postfix 계산기의 Stackoverflowerror
-
19-09-2019 - |
문제
다음 수업은 다른 프로그램에서 사용됩니다. 액세스되면 stackoverflowerror를 던집니다. 이것은 대학에서 프로젝트로해야 할 포스트 픽스 계산기의 일부입니다.
모든 도움을 주셔서 감사합니다. 미리 감사드립니다. 나는 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;
}
}
해결책
문제는 당신의 것입니다 클래스 mypostfixmachine 개인 분야가 있습니다 MyPostfixmachine MPM a로 초기화됩니다 새로운 mypostfixmachine. 이 새로운 MyPostFixMachine에는 새로운 MyPostFixMachine으로 초기화되는 개인 필드 MyPostFixMachine MPM이 있기 때문에 얻을 수 있습니다. :) 이것은 영원히 계속됩니다 (또는 스택이 가득 찰 때까지).
다음은 문제가있는 코드입니다.
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이 사라져야합니다.
다른 팁
나는 당신이 어떻게 stackoverflowerror를 얻는 지 잘 모르겠지만 (이 코드에서 루프 나 재귀가 보이지 않음), 한 가지 확실한 문제는 당신의 과도한 사용입니다. Queue.remove()
. 당신이 당신의 줄을 볼 때마다 if
클로즈, 당신은 첫 번째 요소를 제외하고 있습니다. NoSuchElementException
에스.
모든 것에 대해 아무 말도하지 않습니다 EmptyStackException
s 당신은 빈에서 튀어 나오는 것을 가져야합니다. Stack
.
그래서 말하고 싶습니다 ....
- `remove ()`를 호출해야 할 때`remove ()``를 대신 호출하십시오.
- 빈 스택에서 팝업을 그만 두십시오. 입력 대기열에서 해당 값을 가져오고 싶습니까?
- 'stackoverflowerror'를주는 문제는 다른 곳입니다. (내가 무언가를 간과하지 않는 한 - 항상 가능합니다!) 루프 나 재귀 호출을 찾으십시오.