2015-08-31 57 views
2

爲什麼此遞歸countOccurence函數不起作用?這有一個子程序。有沒有辦法做到這一點沒有子程序?它似乎在JavaScript中你必須有一個閉包(子程序功能)的計數器變量,否則它會被重寫每一次!遞歸計算出現次數

function numOccurencesRecursive(arr, val) { 
    //base case. check it if it only has a length of 1 
    var count = 0; 

    function doCount(arr, val) { 
    if (arr[0] === val) { 
     count++; 
    } else { 
     count += doCount(arr.slice(1), val) 
    } 
    return count; 
    } 

    return doCount(arr, val); 
} 

console.log(numOccurencesRecursive([2, 7, 4, 4, 1, 4], 4)); // should return 3 but returns 1 
+0

*刪除*外'count'變量和處理由'返回0'基本情況;然後添加適當的重現情況。你擁有'這個角色是否匹配'所需的所有計數信息?和「接下來的幾個字符有多少匹配?」對於再發生的情況。這將簡化邏輯 - 包括修復此錯誤 - 並使其更接近「理想」遞歸功能。 – user2864740

回答

3

我認爲問題是,你是反覆思考,但使用遞歸方法。

的迭代方法具有可以在每一步更新的全局變量:

function numOccurencesIterative(arr, val) { 
    var count = 0; 
    for(var i=0; i<arr.length; ++i) if(arr[i] === val) ++count; 
    return count; 
} 

然而,使用遞歸方法時,最好避免全局變量。

function numOccurencesRecursive(arr, val) { 
    if(!arr.length) return 0; 
    return (arr[0] === val) + numOccurencesRecursive(arr.slice(1), val); 
} 
+0

哇,酷......你如何添加一個遞歸調用布爾值,然後得到一個數字?你能展示前幾次遞歸調用嗎? – devdropper87

+0

@freezycold布爾轉換爲引擎蓋下的數字「0」或「1」。你可能更喜歡'(arr [0] === val?1:0)' – Oriol

+0

太棒了。我怎麼能重構我的偶數次出現的第一個元素?去編輯上面的代碼以包含我的嘗試 – devdropper87

1

doCount一旦發現匹配就停止遞歸;因此,它永遠不會找到超過1個匹配數。

+0

我沒有看到,你能解釋一點嗎? – devdropper87

1

因此,你所做的只是當你發現這個值時才增加計數,當你發現它時,你的遞歸函數結束了,但是它的另一種方式是,它意味着你必須計數數組中沒有元素,如果你發現某些東西,增加它,然後如果數組爲空,則返回計數。

代碼:

function numOccurencesRecursive(arr, val) { 
//base case. check it if it only has a length of 1 
var count = 0; 

function doCount(arr, val) { 
    if (arr[0] === val) { 
     count++; 
    } else if (!arr.length) { 
     return count; 
    } 
    return doCount(arr.slice(1), val); 
} 

return doCount(arr, val); 
} 

console.log(numOccurencesRecursive([2, 7, 4, 4, 1, 4], 4)); // should return 3 but returns 1 
+0

我不太明白這個函數最初應該做些什麼,我已經修復它:)現在應該可以工作。 – sadiqevani

+0

如果'val === undefined',將會產生一個無限遞歸。我建議在'arr [0] === val'之前檢查'arr.length'。 – Oriol

0

這一定要與所有使用遞歸巢做:

function countItems(arr, item) { 
    var count = 0; 
    for (var i=0; i<arr.length; i++){ 
     if (typeof(arr[i]) == typeof([])){ 
      count += countItems(arr[i], item); 
     } 
     else{ 
      if(typeof(arr[i]) != typeof([])){ 
       if (arr[i] === item){ 
        ++count; 
       } 
      } 
     } 
    } 
    return count; 
}