Frage

Die folgende Klasse wird von einem anderen Programm verwendet. Wenn es zugegriffen wird, wirft er eine Stackoverflow. Dies ist Teil eines Postfix Calculator Ich habe als ein Projekt an meiner Universität zu tun.

Jede Hilfe wäre sehr dankbar, danke im Voraus. Ich bin in Java ganz neu und ich habe keine Ahnung, was zu tun ist.

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;
}

}

War es hilfreich?

Lösung

Das Problem ist, dass Ihre Klasse MyPostfixMachine ein privates Feld hat MyPostfixMachine mpm , die mit einer neuen MyPostfixMachine initialisiert. Da diese neue MyPostfixMachine hat auch ein eigenes Feld MyPostfixMachine mpm, die mit einem neuen MyPostfixMachine initialisiert wird ... Sie es. :) Das geht weiter und weiter für immer (oder bis dem Stapel voll ist).

Hier ist das problematische Stück Code:

public class MyPostfixMachine implements PostfixMachineInterface {

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

    // ...
}

Ich glaube, Sie können einfach auf den privaten Bereich mpm entfernen. Rufen Sie einfach die Methoden auf der aktuellen Instanz ab. Anstatt also:

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

Sie können einfach schreiben:

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

oder (equivallent aber explizite):

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

Wie auch immer, entfernen Sie einfach den privaten Bereich mpm und die Stackoverflow sollten nun verschwunden sein.

Andere Tipps

Ich bin nicht sicher, wie Sie eine Stackoverflow sind immer (ich sehe keine Schleifen oder Rekursion in diesem Code), aber ein bestimmtes Problem ist Ihr übermäßiger Einsatz von Queue.remove(). Jedes Mal, wenn Sie in Ihrem if Klauseln in der Warteschlange suchen, sind Sie lopping-off das erste Element. - Ich dieser Code erwarten würde barfing-out NoSuchElementExceptions sein

Ganz zu schweigen von all den EmptyStackExceptions sollten Sie von knallend aus einem leeren Stack bekommen.

Also ich würde sagen ....

  1. Beenden Aufruf `remove ()`, wenn Sie sollten `peek anrufen ()` statt.
  2. Beenden von einem leeren Stapel knallen; möchten Sie diese Werte aus Ihrer Eingabe Warteschlange zu ziehen, nicht wahr?
  3. Das Problem, das Sie Ihre `StackOverFlowError` geben, ist an anderer Stelle. (Es sei denn, ich bin etwas mit Blick auf - immer möglich) Suchen Sie nach einer Schleife oder einem rekursiven Aufruf.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top