Pergunta

A classe a seguir é usado por outro programa. Quando é acessado, ele lança um StackOverflowError. Isso faz parte de um Postfix Calculator eu tenho que fazer como um projeto na minha universidade.

Qualquer ajuda seria muito apreciada, obrigado antecipadamente. Eu sou muito novo para Java e não tenho idéia do que fazer.

código:

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

}

Foi útil?

Solução

O problema é que a sua classe MyPostfixMachine tem um campo privado MyPostfixMachine MPM que é inicializado com um novo MyPostfixMachine . Desde esta nova MyPostfixMachine também tem um MPM MyPostfixMachine campo privado, que é inicializado com uma nova MyPostfixMachine ... você obtê-lo. :) Este vai sobre e sobre para sempre (ou até sua pilha está cheia).

Aqui é a peça problemática de código:

public class MyPostfixMachine implements PostfixMachineInterface {

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

    // ...
}

Eu acho que você pode simplesmente remover o MPM campo privado. Apenas chamar os métodos na instância atual. Assim em vez de:

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

Você pode simplesmente escrever:

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

ou (equivallent mas mais explícito):

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

De qualquer forma, basta remover o MPM campo privado eo StackOverflowException deve ser ido.

Outras dicas

Eu não sei como você está recebendo um StackOverflowError (Eu não vejo nenhum loops ou recursão neste código), mas um problema definitivo é o seu uso excessivo de Queue.remove(). Toda vez que você olhar para a fila em suas cláusulas if, você está poda-off o primeiro elemento -. Eu esperaria este código a ser vomitar-out NoSuchElementExceptions

Para não falar de todos os EmptyStackExceptions você deve estar recebendo de popping de um Stack vazia.

Então eu diria que ....

  1. Sair chamando `remove ()` quando você deveria estar chamando `espiada ()` em seu lugar.
  2. Sair surgindo a partir de uma pilha vazia; Você quer estar puxando esses valores a partir de sua fila de entrada, sim?
  3. O problema dando-lhe o seu `StackOverFlowError` está em outro lugar. (A menos que eu estou com vista algo - sempre que possível) Procure um loop ou uma chamada recursiva.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top