2015-08-31 107 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; 
}