0

我在我的类中使用了以下代码,目的是进行一轮递归(特别是在相同类型的对象中创建一个对象)。好吧,一轮递归现在就像是 200 轮递归......所以这搞砸了很多东西。以下代码是我调用递归的地方:

//Find Solute
    try{if(iterations == 0){ //RECONDITION::: iterations is equal to zero at start of program and is static!
        remaining = Whitespace.removePreceding(remaining);
        String unused = remaining.substring(0);
        InterpretInput solute = new InterpretInput(remaining);
        solute.begin();
        solute.fixSoluteAmount();
        soluteAmount = solute.getSolventAmount();
        isSolution = true;
        ++iterations;
    }}catch(Exception ex){
    }
    finally{
        System.out.println("Debugging point D");
        findNumber();
        fixSolventAmount();
        fixSoluteAmount();
    }

您会在上面找到“调试点 D”,它被打印了很多次,因此它显然是在使用一堆对象进行递归之后,因此其余代码被搞砸了。我只需要有经验的人指出这是一次递归迭代的缺陷。

如果你需要整个课程,我也会复制/粘贴下面的内容,但它几乎有 200 行......所以是的......(我知道我不应该做那么长的课程,但这个对象需要很多东西它)。

import java.util.ArrayList;

公共类解释输入{

/**
 * @param remaining - The string that was input, what's left to analyze
 */

/**  Variables  */

private String remaining; //The string input by the user, containing what's left to analyze
private static int iterations = 0;

//Solvent Info
private double solventAmount; //The amount of the solvent expressed as final in MOLES
private M solventAmountMeas; //The measurement used in solventAmount
private double solventConc; //The concentration of the solvent
private M solventConcMeas; //The measurement used in solventConc
private E[] solventCompound; //The compound of the solvent
private E[] water = {E.H, E.H, E.O};

//Solute Info
private double soluteAmount; //The amount of solute in the solution

//Type of Data
private boolean isElement = false; //Determines if the information input is only an element
private boolean hasAmount = false; //Determines if the information input has an amount of solvent
private boolean isSolution = false; //determines if the information input is a solution

private int identificationNumber;

/**  Constructor  */

public InterpretInput (String remain){
    remaining = remain;
}


/**  Mutator Methods  
 * @throws Exception */

public void begin() throws Exception{

    //Find Measurement
    FindMeasurements measureObject = new FindMeasurements(remaining);
    while (measureObject.exists() == true){
        measureObject.determineNumber();
        measureObject.determineMeasurement();
        double solventAmountTemp = measureObject.getAmount();
        M solventAmountMeasTemp = measureObject.getMeasurement();
        if( (solventAmountMeasTemp.getType()) == 3 ){
            isSolution = true;
            solventConc = solventAmountTemp;
            solventConcMeas = solventAmountMeasTemp;
        }else{      
            hasAmount = true;
            solventAmount = solventAmountTemp;
            solventAmountMeas = solventAmountMeasTemp;
        }
        remaining = measureObject.getRemaining();


    }

    //Find Compound
    FindCompound comp = new FindCompound(remaining);
    comp.getCompound();
    solventCompound = comp.getValue();
    remaining = comp.getRemaining();
    if (solventCompound.length == 1)
        isElement = true;

    //Find Solute
    try{if(iterations == 0){
        remaining = Whitespace.removePreceding(remaining);
        String unused = remaining.substring(0);
        InterpretInput solute = new InterpretInput(remaining);
        solute.begin();
        solute.fixSoluteAmount();
        soluteAmount = solute.getSolventAmount();
        isSolution = true;
        ++iterations;
    }}catch(Exception ex){
    }
    finally{
        System.out.println("Debugging point D");
        findNumber();
        fixSolventAmount();
        fixSoluteAmount();
    }
}

public void fixSoluteAmount() throws Exception {
    fixSolventAmount();
}

public void fixSolventAmount() throws Exception {
    switch (identificationNumber){ //VIEW findNumber TO SEE INDEX OF THESE CASES

        case 1:{
            //In this situation, there would be nothing to change to begin with
            break;
        }

        case 2:{
            //In this situation, there would be nothing to change to begin with
            break;
        }

        case 3:{
            solventAmount *= solventAmountMeas.ofBase();
            switch (solventAmountMeas.getType()){
                case 1:{ //volume
                    if (!solventCompound.equals(water))
                        throw new Exception();
                    else{
                        solventAmount *= 1000; //Convert 1000g for every 1L
                        double molarMass = 0;
                        for (E e : solventCompound)
                            molarMass += e.atomicMass();
                        solventAmount /= molarMass; //convert to moles
                    }
                }

                case 2:{ //mass
                    double molarMass = 0;
                    for (E e : solventCompound)
                        molarMass += e.atomicMass();
                    solventAmount /= molarMass; //convert to moles
                }
            }
        }

        case 4:{
            if(solventAmountMeas.equals(M.m)){
                throw new Exception(); //I AM TAKING OUT THIS FEATURE, IT WILL BE TOO DIFFICULT TO IMPLEMENT
                                       //BASICALLY, YOU CANNOT USE MOLALITY IN THIS PROGRAM ANYMORE
            }
        }

        case 5:{
            if(solventAmountMeas.equals(M.m))
                throw new Exception(); //I AM TAKING OUT THIS FEATURE, IT WILL BE TOO DIFFICULT TO IMPLEMENT
                                       //BASICALLY, YOU CANNOT USE MOLALITY IN THIS PROGRAM ANYMORE
            double molarMass = 0;
            for (E e : solventCompound)
                molarMass += e.atomicMass();
            solventAmount /= molarMass; //convert to moles
        }
    }
}

public void findNumber(){
    /**
     * 1 = Element
     * 2 = Compound
     * 3 = measured amount of compound
     * 4 = specific concentration of solution
     * 5 = Measured amount of specific concentration of solution
     * */

    if(isElement==true)
        identificationNumber = 1;
    else if(isSolution == false && hasAmount == false)
        identificationNumber = 2;
    else if(isSolution == false && hasAmount == true)
        identificationNumber = 3;
    else if(isSolution == true && hasAmount == false)
        identificationNumber = 4;
    else
        identificationNumber = 5;
}


/**  Accessory Methods  */

public double getSolventAmount(){
    return solventAmount;
}

public double getSoluteAmount(){
    return soluteAmount;
}

public double getConcentration(){
    return solventConc;
}

public E[] returnCompound(){
    return solventCompound;
}

}
4

2 回答 2

0

您的Begin函数似乎在增加iterations变量之前调用自己。这将导致无限递归。请参阅HERE下面代码中的注释。

//Find Solute
try{if(iterations == 0){
    remaining = Whitespace.removePreceding(remaining);
    String unused = remaining.substring(0);
    InterpretInput solute = new InterpretInput(remaining);

    // HERE - calls itself again, prior to incrementing
    // iterations variable
    solute.begin();

    solute.fixSoluteAmount();
    soluteAmount = solute.getSolventAmount();
    isSolution = true;

    // HERE - iterations is incremented, but too late
    ++iterations;
}}catch(Exception ex){
}

要解决递归问题,您应该在调用iterations之前递增。begin

于 2013-03-30T16:05:35.260 回答
0

这里的代码很乱;弄清楚目标是什么有点困难。您要对 in 中的字符串做什么InterpretInput,为什么它采用如此复杂的解决方案(递归构建的对象)而不是循环甚至只是递归方法?

然而,除此之外,似乎没有任何方法可以让您的递归中断。它这样做的唯一有效方法是 if iterations != 0,这永远不会是真的,因为唯一的时间iterations增加是在递归调用之后。因此,我认为程序完全终止的唯一原因是堆栈溢出,但异常被空catch块捕获。尝试在该块中打印一些东西;我敢打赌,即使您不希望它发生,这也是代码的去向。

于 2013-03-30T16:06:03.180 回答