【问题标题】:JavaScript bug: function returns NaN even though typeof function returns "number"JavaScript 错误:即使 typeof 函数返回“数字”,函数也会返回 NaN
【发布时间】:2021-06-01 14:43:33
【问题描述】:

我想找到由 给定 数的排列产生的最大数。

如果给定的数是123,那么它的排列得到的最大数是321。

编辑

我通过改变取得了一些进展

if (str.length === 0) return "";
if (str.length === 1) return str;

if (str.length === 0) {
    return "";
} else {
    return str;
}

然而,一个问题仍然存在:该函数返回一个字符串。实际上,数组成员是 strings 而不是 numbers

function findPerms(num) {
    var str = num.toString();
    
  if (str.length === 0) {
        return "";
    } else {
        return str;
    }
 
  let result = [];
  for (let i = 0; i < str.length; i++) {
    const currentChar = str[i];
    const remainingChars = str.slice(0, i) + str.slice(i + 1);
    for (let j = 0; j < remainingChars.length; j++) {
      result.push(Number(currentChar + findPerms(remainingChars)[j]));
    }
  }

    result.sort(function(a, b) {
        return a - b;
    });

  return result[result.length - 1];
    
}


console.log(findPerms(11121));
console.log(typeof findPerms(11121));

为此我做了:

function findPerms(num) {
  var str = num.toString();

  if (str.length === 0) return "";
  if (str.length === 1) return str;
  let result = [];
  for (let i = 0; i < str.length; i++) {
    const currentChar = str[i];
    const remainingChars = str.slice(0, i) + str.slice(i + 1);
    for (let j = 0; j < remainingChars.length; j++) {
      result.push(Number(currentChar + findPerms(remainingChars)[j]));
    }
  }

  result.sort(function(a, b) {
    return a - b;
  });

  return result[result.length - 1];

}

console.log(findPerms(11121));
console.log(typeof findPerms(11121));

问题

我一定是犯了一个我无法发现的错误,因为上面的函数返回 NaN(即使 typeof findPerms(11121) 返回“数字”)。

我的错误在哪里?

【问题讨论】:

  • 您的问题是为什么它返回NaN 或为什么返回typeof NaN === "number"(这将与Why does typeof NaN return 'number'? 重复)?
  • 你做了什么调试?您是否尝试过断言 currentChar + findPerms(remainingChars)[j] 始终是您期望的值?例如。 findPerms(remainingChars)[j] 在某个时候是 undefined。了解how to debug small programsRubber Duck Debug您的代码并尝试解释这是为什么。
  • @SebastianSimon 我的问题是为什么函数返回NaN而不是数组中的最大数。
  • @Razvan Zamfir ,findPerms 的返回类型是什么?让我猜猜它是一个空字符串("")还是一个字符(“1..9”)?当你从 findPerms(remainingChars)[j] 读取一个值时,其中 j 是一个索引,它变成了 undefined ,那么你怎么能用 undefiend 添加任何数字呢? number + undefined = NaN,所以result 中有很多NaN 值,其中result 的最后一项也是NaN,但是您的预期输出值是多少?
  • 错字: findPerms( remainingChars )[ j ] ->findPerms( remainingChars[ j ] ).

标签: javascript ecmascript-6 ecmascript-5


【解决方案1】:

您的代码存在一些问题,但让我们先尝试正确定义需求。 如果我了解您想要做的是查找数字的所有排列并选择数字中数字的最高可能排列。 您正在尝试做的是这样的:

  1. 创建一个空列表
  2. 循环遍历初始号码的数字。
  3. 对于每个数字循环,通过剩余数字找到所有可能的组合,并将它们添加到初始空列表中。
  4. 在您拥有列表中所有可能的数字组合后,对它们进行排序并返回最高的结果。

这里有2个问题,首先是代码执行有一些错误,你的算法效率不是很高。 让我们解决第一个问题: 当您创建结果列表时,您在递归函数中定义它,这意味着它将在每次递归调用时被一个空数组覆盖。通常,当您应用此技术时,您要么在递归函数之外定义结果数组,要么将其作为参数传递,以便能够迭代结果。 您似乎没有很好地了解函数范围和闭包在 JS 中的工作方式。我建议为此阅读 MDN 上的一些资源。

这里的另一个问题是你希望函数接收一个数字作为参数,但是当你调用它时

result.push(Number(currentChar + findPerms(remainingChars)

remainingChars 是一个字符串,因此是 NaN 结果。

现在开始第二个问题。考虑到您想要从一系列数字中获得最大可能的数字,您可以将数字从高到小排序并提供结果。 例如: 如果数字是 18,则可以将其排序为 [8, 1] 之类的数组,然后将其连接到 81。 代码可能看起来像:

function findHighestPerm(no) {
  const arr = no.toString().split('');
  return parseInt(arr.sort((a, b) => b - a).join(''));
}

PS:我知道我的代码不是最高效或最优雅的,但我只是懒惰而且它有效;)

【讨论】:

    【解决方案2】:

    编辑
    我认为这是您想要做的。
    使用递归创建一个数字的所有数字排列的数组。
    对数组进行排序。
    返回具有最大数字的排列。

    这可以通过将问题分解为两个函数来完成。
    第一个函数返回一个数字的所有排列组成的数组。
    第二个函数从第一个函数获取一个数组结果,然后对其进行排序。然后它返回最后一个值。
    您的递归运行不正常。这就是它不起作用的原因。

    <html><head><title>6770990</title>
    <script>
    function findPerms(num) {
      var str = num.toString(); var result = [];
      if (str.length == 0) return result;
      if (str.length == 1) return [parseInt(str)];
      for (var i = 0; i < str.length; i++) {
        const currentChar = str[i];
        const remainingChars = str.slice(0, i) + str.slice(i + 1)
        var perms = findPerms(remainingChars) //----Permutation array of remaining chars.
        for (var j = 0; j < perms.length; j++) {
          result.push(parseInt("" + currentChar + perms[j]));
        }
      }
      return result; //----All permutations for num.
    }
    function findLargestPerm(num)
    { var perms = findPerms(num); perms.sort(function(a,b) {return a-b;});
      return perms[perms.length-1];
    }
    </script>
    </head></body>
    <script>
    var r = findLargestPerm(11121); alert("r=" + r);
    </script>
    </body></html>
    

    上一个答案

    将数字以相反的顺序排序并连接成一个数字会更有效。这将是最大的排列。

    函数 findPerms() 试图找到一组数字的最大排列。有时将函数重命名为它的功能会有所帮助,这样更容易遵循逻辑。

    再次使用递归调用函数的行只需要为每个当前字符调用一次。

    以下代码显示了发生的步骤。

    <html><head><title>6770990</title>
    <script>
    var msg="";
    function findLargestPermutation(num)
    { var str = num.toString(); msg += "findLargestPermutation(" + str + ")<br>";
      if (str.length === 0) return "";
      if (str.length === 1) return str;
      let result = [];
      for (let i = 0; i < str.length; i++)
      { const currentChar = str[i];
        const remainingChars = str.slice(0, i) + str.slice(i + 1);
        msg += "currentChar=" + currentChar + " remainingChars=" + remainingChars + "<br>";
        //----The j loop should be removed and just use this line.
        var num = Number(currentChar + findLargestPermutation(remainingChars));
        msg += "num=" + num + "<br>";
        result.push(num);
      }
      result.sort(function(a, b) {return a - b;});
      msg += "findLargestPermutation()=" + result[result.length - 1] + "<br>";
      return result[result.length - 1];
    }
    </script>
    </head><body>
    <div id="div"></div>
    <script>
    var lp = findLargestPermutation(11121);
    alert("lp=" + lp + " typeof lp=" + typeof lp);
    document.getElementById("div").innerHTML = msg;
    </script>
    </body></html>
    

    【讨论】:

    • 恐怕没有用。代码没有运行。
    猜你喜欢
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多