2016-05-12 42 views
2

我很輕鬆地製作了Sudoku檢查器/求解器,但是我需要一個能夠告訴我有多個解決方案的解決方案,並且無法將其包裹在它周圍。我發現了一個工作算法,但我試圖理解它爲什麼工作。這是從this question,答案由@fabianJava:遞歸數獨解法計數算法

複製以下提供:

// returns 0, 1 or more than 1 depending on whether 0, 1 or more than 1 solutions are found 
static byte solve(int i, int j, int[][] cells, byte count /*initailly called with 0*/) { 
    if (i == 9) { 
     i = 0; 
     if (++j == 9) 
      return 1+count; 
    } 
    if (cells[i][j] != 0) // skip filled cells 
     return solve(i+1,j,cells, count); 
    // search for 2 solutions instead of 1 
    // break, if 2 solutions are found 
    for (int val = 1; val <= 9 && count < 2; ++val) { 
     if (legal(i,j,val,cells)) { 
      cells[i][j] = val; 
      // add additional solutions 
      count = solve(i+1,j,cells, count)); 
     } 
    } 
    cells[i][j] = 0; // reset on backtrack 
    return count; 
} 

我想實現它,因爲它應該,它的工作原理。然而,儘管我認爲我明白代碼的每個部分都是,但我無法理解它爲什麼可行。

第一個:第一個if語句在達到第2個數組中的最後一個數字後停止該方法。我找到了這個解決方案,但是爲什麼它能夠找到多個解決方案?找到解決方案後,該方法不應該返回0 + 1 = 1嗎?

if (cells[i][j] != 0)後爲什麼遞歸調用solve(...)需要在它前面return聲明?我做了幾個遞歸算法,但總是通過再次調用該方法。

第三:如果沒有找到合適的數字,則for循環停止,並且0被輸入到單元格位置。由於它應該已經有0,不應該回溯到0而不是當前的最後一個地方?至少我是這樣解決自己的問題的。

第四:在回溯設置後,只有return count。爲什麼程序還在工作?不應該只是返回count = 0,並在面對不允許任何數字的第一個地方後停止?如何在最後沒有遞歸調用?

如果你在這個棘手的問題上做得這麼遠,很顯然,我理解一些完全錯誤的東西。我非常感謝幫助/解釋,因爲使用代碼不理解的代碼是完全失敗的。

回答

0

好了,谷歌提供優雅哈佛大學的演講簡報: http://www.fas.harvard.edu/~cscie119/lectures/recursion.pdf

如果別人有越來越遞歸回溯問題,我建議你檢查出來。非常短但內容豐富。

我的問題似乎只是我愚蠢地(至少事後)認爲方法停止後,它會自動遞歸調用自己。我忘記了它從它所做的遞歸調用中獲得結果後,它將自己執行到最後。有趣的是,你如何使用小時數解決問題,只是因爲你的初始思維過程有缺陷。那麼,我猜想,生活和學習。