2013-07-25 31 views
1

我一直在學習Java大約一個月,並通過閱讀本網站上其他人的問題(和答案)瞭解了很多。我不認爲這是之前問過的(但是如果有的話,我會欣賞一個指針......)爲什麼我的遞歸Java方法中的字段更改?

在下面的代碼中,幾乎所有沒有縮進的東西都是錯誤檢查打印輸出,所以代碼比看起來要短很多。代碼是我嘗試使用遞歸來列出numBalls球可以放置在numBins個分檔中的所有方法。

主要問題:該方法工作正常numBins < 3.只要numBins設置爲3,endList字段(遞歸調用)已經超過1「行」,並儘快爲J命中1直接在下面的循環中,indexList字段被更改。例如,主方法(配置時)中的calling testList = distributeBallsInBins(1,3,"");會導致indexList的第二行從{0 1 0}更改爲{0 0 1}(如輸出中所示),但我看不到/爲什麼當我所做的所有事情都改變到下一個j(即從j = 0到j = 1)

第二個問題:我用int[]代替了所有Integer[]事件,似乎沒有區別。應該有嗎?我想我需要詳細瞭解原始類型和引用類型之間的區別,但我並不真正瞭解這裏的區別。

謝謝你在前進, 邁克

import java.util.*; 

public class testRecursion 
{ 
    public static List<Integer[]> distributeBallsInBins(int numBalls, int numBins, String tmpTxt) 
    { 
     if (numBins==1) 
     { 
      List<Integer[]> lastList = new ArrayList<Integer[]>(); 
      lastList.add((new Integer[] {numBalls})); 
      return lastList; 
     } 
     else if (numBalls==0) 
     { 
      List<Integer[]> lastList = new ArrayList<Integer[]>(); 
      Integer[] tmpNum = new Integer[numBins]; 
      for (int k=0; k<numBins; k++) 
       tmpNum[k] = 0; 
      lastList.add(tmpNum); 
      return lastList; 
     } 
     else 
     { 
      List<Integer[]> indexList = new ArrayList<Integer[]>(); 
      for (int i=numBalls; i>=0; i--) 
      { 
       Integer[] newLine = new Integer[numBins]; 
       newLine[0] = i; 
       List<Integer[]> endList = distributeBallsInBins((numBalls-i), (numBins-1), (tmpTxt + " ")); 
       for (int j=0; j<endList.size(); j++) 
       { 
        Integer[] newLineEnd = endList.get(j); 
        for (int k=0; k<numBins-1; k++) 
         newLine[k+1] = newLineEnd[k]; 
        indexList.add(newLine); 
       } 
      } 
     return indexList; 
     } 
    } 

    public static void main(String[] args) 
    { 
     List<Integer[]> testList = distributeBallsInBins(1,3,""); 
    } 
} 
+2

讓我們讓世界變得更美好 - 縮進你的代碼。 – Maroun

+0

請使用空格而不是製表符縮進您的代碼 - 在Stack Overflow中,製表符不能很好地工作。 –

+0

我做了縮進(除了錯誤檢查,我不這樣做,我可以輕鬆地拿出它),但使用標籤 - 我已經編輯它來清理它。感謝提示 – Mike

回答

0

你的問題是,你總是修改,並插入相同的陣列到你的結果。由於Java處理每個引用的所有對象,因此最終會得到一個包含相同數組的列表。

所以,你需要或者將它添加到列表之前clone的數組:newLine數組新的每次

indexList.add(newLine.clone()); 

或創建迭代您j -loop:

for (int j = 0; j < endList.size(); j++) { 
    Integer[] newLine = new Integer[numBins]; 
    newLine[0] = i; 
    Integer[] newLineEnd = endList.get(j); 
    for (int k = 0; k < numBins - 1; k++) 
     newLine[k + 1] = newLineEnd[k]; 
    indexList.add(newLine); 
} // next j 

關於對象與基元相比:更改爲int[]沒有幫助,因爲array本身仍然是Object,因此通過引用傳遞。

+0

邁克爾,謝謝。我將不得不閱讀克隆,但第二個修復工作很好。我嘗試了很多東西,但不是那樣(我認爲這樣做效率更高 - 不必每次都設置newLine [0]值)。我想我需要了解更好的參考。 – Mike

+0

邁克爾,關於int []與Integer [],我沒有想到解決這個問題,只是有點驚訝,它沒有什麼區別(在這個程序中,至少)。再次感謝。 – Mike

0

只需更換這行

indexList.add(newLine); 

indexList.add(newLine.clone()); 

這將工作...... 這將通過新的陣列,而不是通過舊陣列的參考... ...