StackOverFlowError в постфиксном калькуляторе Java - PullRequest
0 голосов
/ 10 марта 2010

Следующий класс используется другой программой.При обращении к нему выдается ошибка 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;
}

}

Ответы [ 2 ]

6 голосов
/ 10 марта 2010

Проблема в том, что ваш класс 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 должно исчезнуть.

0 голосов
/ 10 марта 2010

Я не уверен, как вы получаете StackOverflowError (я не вижу циклов или рекурсии в этом коде), но одна определенная проблема - это ваше чрезмерное использование Queue.remove().Каждый раз, когда вы смотрите на очередь в ваших if предложениях, вы отсекаете первый элемент - я ожидаю, что этот код будет сглаживать NoSuchElementException s.

Ничего не сказатьиз всех EmptyStackException s, которые вы должны получать, щелкая пустым Stack.

Так что я бы сказал ....

  1. Прекратите вызывать `remove ()`когда вы должны вызывать` peek () `.
  2. Выйти, выскочив из пустой стопки;Вы хотите получить эти значения из входной очереди, да?
  3. Проблема с предоставлением вам вашего `StackOverFlowError` находится в другом месте.(Если я не пропускаю что-то - всегда возможно!) Ищите цикл или рекурсивный вызов.
...