2014-09-11 69 views
-1

在下面的代碼中,我將檢查一個字符串是否在某個網格中是「可拼寫的」,類似於Scrabble。如果字母直接位於當前字母的上方,下方,左側或右側,則可以使用字母。例如,「bcd」應該返回TRUE,而「bcdn」應該返回FALSE。Javascript:無法在遞歸函數調用中重新分配變量

功能執行完全按照我的預期,除了行32-33。根據我的理解,wordExists = true行應覆蓋第9行的原始聲明。

我錯過了什麼?

repl.it鏈接= http://repl.it/Yhh/5

var grid = [ 
    ['a','b','c','d'], 
    ['e','f','g','h'], 
    ['i','j','k','l'], 
    ['m','n','o','p'] 
]; 

function doesWordExist(word, grid) { 
    var wordExists = false; 
    for (var i = 0, end = grid.length; i < end; i++){ 
     for (var j = 0, stop = grid[0].length; j < stop; j++) { 
      if (word[0] === grid[i][j]) { 
       doesLetterExist(word, i, j, 1); 
      } 
     } 
    } 
    return wordExists; 
} 

function isMatch(letter,i,j) { 
    return (
     grid[i] !== undefined && 
     grid[i][j] !== undefined && 
     letter === grid[i][j] 
    ); 
} 

function doesLetterExist(word, i, j, depth) { 
    console.log('i:' +i + " - j:" + j); 
    var letter = word[depth]; 
    if (letter === undefined) { 
     wordExists = true; 
     console.log('can\'t re-define global "wordExists" variable :-('); 
    } 
    if (isMatch(letter,i, j + 1)) { // look right, j + 1 
     doesLetterExist(word, i, j + 1, depth + 1); 
    } else if (isMatch(letter, i, j -1)) { // look left, j - 1 
     doesLetterExist(word, i, j - 1, depth + 1); 
    } else if (isMatch(letter, i - 1, j)) { // look up, i - 1 
     doesLetterExist(word, i - 1, j, depth + 1); 
    } else if (isMatch(letter, i + 1, j)) { // look down, i + 1 
     doesLetterExist(word, i + 1, j, depth + 1); 
    } 
} 

doesWordExist('bcd', grid); 

謝謝!

編輯:我從標題中刪除了「全局」一詞。我錯誤地將在第一個函數中實例化的變量稱爲全局變量。它應該是可用的,並且可以從其範圍內的所有功能更改?這就是我所說的'全球',它對所有兒童功能都是全球性的。

+2

你可以重構你的算法不依賴於一個全局變量。 – elclanrs 2014-09-11 05:33:31

+1

'function doesWordExist(word,grid){ var wordExists = false;'< - not global – epascarello 2014-09-11 05:37:38

+0

'if(letter === undefined){ wordExists = true;'< - 實際上是全局的 – epascarello 2014-09-11 05:39:58

回答

1

它應該可以和多變的所有職能範圍內它的範圍右取出var?對於所有兒童功能來說,這感覺都很全面

是。只有isMatchdoesLetterExist不是doesWordExist的子功能!他們被宣佈在身體之外。我們需要他們,這樣他們就可以訪問他們的父母範圍:

function doesWordExist(word, grid) { 
    var wordExists = false; 
    for (var i = 0, end = grid.length; i < end; i++){ 
     for (var j = 0, stop = grid[0].length; j < stop; j++) { 
      if (word[0] === grid[i][j]) { 
       doesLetterExist(word, i, j, 1); 
      } 
     } 
    } 
    return wordExists; 

    function doesLetterExist(word, i, j, depth) { 
     console.log('i:' +i + " - j:" + j); 
     var letter = word[depth]; 
     if (letter === undefined) { 
      wordExists = true; 
     } 
     if (isMatch(i, j + 1)) { // look right, j + 1 
      doesLetterExist(word, i, j + 1, depth + 1); 
     } else if (isMatch(i, j -1)) { // look left, j - 1 
      doesLetterExist(word, i, j - 1, depth + 1); 
     } else if (isMatch(i - 1, j)) { // look up, i - 1 
      doesLetterExist(word, i - 1, j, depth + 1); 
     } else if (isMatch(i + 1, j)) { // look down, i + 1 
      doesLetterExist(word, i + 1, j, depth + 1); 
     } 
     function isMatch(i, j) { 
      return grid[i] !== undefined && 
        grid[i][j] !== undefined && 
        letter === grid[i][j]; 
     } 
    } 
} 

同樣的isMatch功能現在可以訪問letter變量,因爲它是doesLetterExist功能的一部分,它並不需要再次作爲爭論通過。


但是,雖然你的函數現在可以工作,但它仍然不是最優的。當wordExists設置爲true時,您應該能夠突破doesWordExist - 您已經知道該解決方案。目前,你正在繼續循環 - 這是一個相當繁重的循環。嘗試改進您的原始算法(使用3個單獨的函數),以便您沒有該「全局」變量wordExists變量,而只使用return在每個函數中 - doesLetterExist應立即return true找到該字母,並且只有在篩選完所有遞歸調用後才返回false

+0

這正是我所需要的。我錯誤地認爲僅僅調用另一個函數就足以訪問其父函數的作用域。我現在明白,如果函數需要捕獲父函數的範圍,那麼函數必須在任何父函數中聲明和調用。關於優化的建議非常好。我記下了你的觀點並重構了代碼([http://repl.it/Yhh/7](http://repl.it/Yhh/7))。再次感謝您的幫助! – a15n 2014-09-11 18:31:22

2

您定義wordExists上線的局部變量9

var wordExists = false; 

從上面

+0

把它拿出來會導致一個「工作」的腳本,但它不是一個好的解決方案。你不能提出更好的建議嗎? – Bergi 2014-09-11 05:41:06

+0

@Bergi該OP特別詢問了全局變量,所以我假設他有這個理由需要它在這方面 – 2014-09-11 05:47:31

+0

@Bergi是正確的,但我應該更清楚。我希望所有的變量都是函數中的自容器。我已更新原始帖子。 – a15n 2014-09-11 06:53:05

相關問題