【问题标题】:Recursion and Loops - Maximum Call Stack Exceeded递归和循环 - 超过最大调用堆栈
【发布时间】:2014-06-12 07:16:23
【问题描述】:

我正在尝试构建一个函数,将字符串中的所有数字相加...例如,“dlsjf3diw62”最终将是 65。

我想聪明点,拼凑出一个递归函数:

function NumberAddition(str) { 
  var numbers='1234567890';
  var check=[];
  str=str.split[''];
  function recursive(str,check) {
    if (str.length==0)
      return check;
    else if (numbers.indexOf(str[0])>=0)
    {
      for (i=0;i<str.length;i++){
        if (numbers.indexOf(str[i])<0)
          check.push(str.slice(0,i));
        str=str.slice(i);
        return recursive(str,check);
      }
    }
    else
      str.shift();
    return recursive(str,check);
  }

您会看到,我正在尝试将我的数字作为数组返回到名为 check 的数组中。不幸的是,我超出了最大调用堆栈大小,我不知道为什么!递归确实有一个基本案例!一旦 str 不再有任何内容,它就会结束。为什么这行不通?我有什么遗漏吗?

-会

【问题讨论】:

  • 学习使用浏览器的开发人员工具并逐步执行您的代码。此外,还有一种更简单的方法可以实现您正在尝试的目标。
  • 您发布的代码似乎缺少某些内容;很难判断函数在哪里结束,尤其是最后几行看起来有问题。缺少一个大括号。
  • 更简单的方法是什么?
  • @user3546595 用正则表达式去掉数字子串,然后减少结果。
  • 对不起,我没有复制粘贴到最后一行。确实是名为“递归”的函数不起作用。

标签: javascript recursion


【解决方案1】:

您可以使用正则表达式通过更简单的解决方案实现相同的目的,如下所示:

var str = 'dlsjf3diw62';
var check = str.match(/\d+/g); // this pattern matches all instances of 1 or more digits

然后,要对数字求和,您可以这样做:

var checkSum = 0;
for (var i = 0; i < check.length; i++) {
    checkSum += parseInt(check[i]);
}

或者,稍微紧凑一点:

var checkSum = check.reduce(function(sum, num){ return sum + parseInt(num) }, 0);

【讨论】:

  • 新增内容在哪里?
  • 好吧,他们的代码只产生了数组,所以我想我会匹配它。
  • 我想你想要/\d+/g
  • 您在/\d+/g 中缺少+,因为OP 说dlsjf3diw62 的输出应该是65 而不是11。
  • 你说得对,老实说,我不明白他们是如何得到 65 的!
【解决方案2】:

您的递归不起作用的原因是您确实进入了for 循环,因为您找到了一个数字,但数字继续到字符串的末尾。如果发生这种情况,for 循环内的return 将永远不会发生,并且循环结束。之后,.shift() 确实 不会 发生,因为它位于 else 分支中,因此您返回重新处理相同的字符串。

您不应该以这种方式解决这个特定问题,但该代码很好地说明了在 if 主体中包含 return 语句后跟 else 的反模式。如果它看起来像这样,您的代码会更清晰(并且可以工作):

function recursive(str, check) {
    if (str.length == 0)
        return check;

    if (numbers.indexOf(str[0]) >= 0) {
        // Find the end of the string of digits, or
        // the end of the whole thing
        for (var i = 0; i < str.length && numbers.indexOf(str[i]) >= 0; i++);

        check.push(str.slice(0, i));
        str = str.slice(i);
        return recursive(str, check);
    }

    // A non-digit character
    str.shift();
    return recursive(str, check);
}

在那个版本中,没有else 子句,因为两个if 子句总是涉及returnfor 循环更改为简单地找到“i”的正确值以进行后续切片。

edit — 这不能解决的一件事是您将 arrays 推送到“检查”列表中。也就是说,子字符串“62”将作为数组["6", "2"] 推送。这不是一个大问题。在正确的位置添加.join() 即可解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-18
    • 1970-01-01
    • 2021-05-20
    • 2020-07-10
    • 2014-08-03
    • 2018-03-02
    • 2021-07-24
    • 2019-09-09
    相关资源
    最近更新 更多