2013-03-30 6 views
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; 

공용 클래스 InterpretInput는 {

/** 
* @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; 
} 

} 

답변

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 호출에 증가한다, 재귀 문제를 해결하려면.

0

여기 코드는 꽤 지저분합니다. 목표가 무엇인지 알아내는 것은 약간 어렵습니다. 무엇 문자열을 InterpretInput에 넣으려고합니까? 루프 나 재귀 메서드와 달리 복잡한 솔루션 (재귀 적으로 작성된 개체)이 필요한 이유는 무엇입니까?

그러나 그 이상의 경우 재귀가 중단 될 수있는 방법이 없어 보이지 않습니다. 유효한 방법은 iterations != 0 일 경우에만 적용되며, 이는 iterations 시간 만 반복되는 것이 재귀 호출 이후이므로 true가 아닙니다. 따라서 프로그램이 종료되는 유일한 이유는 스택 오버플로가 발생하지만 예외는 빈 catch 블록에 걸렸습니다. 그 블록에 무엇인가를 인쇄 해보십시오. 그 코드가 기대하지 않는 곳에서도 코드가 나올 곳입니다.

관련 문제