无法检测 JS 中的 'while loop' 中无限循环的原因
Can't detect the cause of infinite loop in a 'while loop' in JS
我的 while 循环中有一个无限循环,我找不到原因。
这是一个简单的函数,它 return 是参数数字的总和。我使用 while 循环,因为它需要将数字相加,直到它落在一位数字上。
我确保我添加了一条语句,以确保在某个点循环会中断。但显然不会。
function digital_root(n) {
num = n;
sum = 0;
while (num.toString().length>1){
for (i=0; i<num.toString().length; i++) {
sum += parseInt(num.toString()[i])
}
num = sum;
}
return sum;
}
digital_root(456)
我收到一条警告,提示我在第 4 行(while 循环)有一个无限循环。
我希望 num=sum
将新整数(位数减少)重新分配给 num
变量,从而在某个时候跳出循环。这有错吗?
更让我困惑的是,我用来调试问题的大多数 JS 编辑器 return 输出,但这需要很长时间。那么这是一个无限循环还是不是?
您有一个嵌套循环结构,其中第一个条件始终为真。
如果只获取小于 10 的数字,您可以再次调用该函数作为递归。
function digital_root(n) {
var num = n.toString(), // declare and use the string value
sum = 0,
i;
for (i = 0; i < num.length; i++) {
sum += parseInt(num[i], 10)
}
return sum > 9
? digital_root(sum)
: sum;
}
console.log(digital_root(456));
既然你已经得到了答案,这里是满足结果的另一种方法
function digital_root(n) {
// convert the number to string
// use split to create an array of number viz ['4','5','6']
// use reduce to sum the number after converting to number
// 0 is the initial value
return n.toString().split('').reduce((a, c) => a + parseInt(c, 10), 0)
}
console.log(digital_root(456))
避免所有导致您所面临情况的嵌套循环,我宁愿以更易读的方式进行。
function digital_root(n) {
sum = n;
while(sum.toString().length > 1) {
sum = sum.toString()
.split('')
.map(digit => parseInt(digit, 10))
.reduce((acc, cur) => acc + cur);
}
return sum;
}
console.log(digital_root(456));
在 re-reading 这个问题之后,我注意到您正在尝试将整数缩减为单个数字。您的代码的问题是 sum
仅在 while 循环之前设置为 0
。这意味着它没有为第二个、第三个...重置。运行.
将 sum = 0
移动到 while 循环中解决了这个问题。我还在顶部添加了变量声明以避免设置全局变量。
function digital_root(n) {
var num, sum, i;
num = n;
while (num.toString().length > 1) {
sum = 0;
for (i = 0; i < num.toString().length; i++) {
sum += parseInt(num.toString()[i]);
}
num = sum;
}
return sum;
}
console.log(digital_root(456));
这里用递归的方式写的,我个人比较喜欢的风格:
function digital_root(integer) {
// guard against things that might result in an infinit loop, like floats
if (!Number.isInteger(integer) || integer < 0) return;
const chars = integer.toString().split("");
if (chars.length == 1) return integer;
return digital_root(
chars.map(char => parseInt(char))
.reduce((sum, digit) => sum + digit)
);
}
console.log(digital_root(456));
我的 while 循环中有一个无限循环,我找不到原因。
这是一个简单的函数,它 return 是参数数字的总和。我使用 while 循环,因为它需要将数字相加,直到它落在一位数字上。 我确保我添加了一条语句,以确保在某个点循环会中断。但显然不会。
function digital_root(n) {
num = n;
sum = 0;
while (num.toString().length>1){
for (i=0; i<num.toString().length; i++) {
sum += parseInt(num.toString()[i])
}
num = sum;
}
return sum;
}
digital_root(456)
我收到一条警告,提示我在第 4 行(while 循环)有一个无限循环。
我希望 num=sum
将新整数(位数减少)重新分配给 num
变量,从而在某个时候跳出循环。这有错吗?
更让我困惑的是,我用来调试问题的大多数 JS 编辑器 return 输出,但这需要很长时间。那么这是一个无限循环还是不是?
您有一个嵌套循环结构,其中第一个条件始终为真。
如果只获取小于 10 的数字,您可以再次调用该函数作为递归。
function digital_root(n) {
var num = n.toString(), // declare and use the string value
sum = 0,
i;
for (i = 0; i < num.length; i++) {
sum += parseInt(num[i], 10)
}
return sum > 9
? digital_root(sum)
: sum;
}
console.log(digital_root(456));
既然你已经得到了答案,这里是满足结果的另一种方法
function digital_root(n) {
// convert the number to string
// use split to create an array of number viz ['4','5','6']
// use reduce to sum the number after converting to number
// 0 is the initial value
return n.toString().split('').reduce((a, c) => a + parseInt(c, 10), 0)
}
console.log(digital_root(456))
避免所有导致您所面临情况的嵌套循环,我宁愿以更易读的方式进行。
function digital_root(n) {
sum = n;
while(sum.toString().length > 1) {
sum = sum.toString()
.split('')
.map(digit => parseInt(digit, 10))
.reduce((acc, cur) => acc + cur);
}
return sum;
}
console.log(digital_root(456));
在 re-reading 这个问题之后,我注意到您正在尝试将整数缩减为单个数字。您的代码的问题是 sum
仅在 while 循环之前设置为 0
。这意味着它没有为第二个、第三个...重置。运行.
将 sum = 0
移动到 while 循环中解决了这个问题。我还在顶部添加了变量声明以避免设置全局变量。
function digital_root(n) {
var num, sum, i;
num = n;
while (num.toString().length > 1) {
sum = 0;
for (i = 0; i < num.toString().length; i++) {
sum += parseInt(num.toString()[i]);
}
num = sum;
}
return sum;
}
console.log(digital_root(456));
这里用递归的方式写的,我个人比较喜欢的风格:
function digital_root(integer) {
// guard against things that might result in an infinit loop, like floats
if (!Number.isInteger(integer) || integer < 0) return;
const chars = integer.toString().split("");
if (chars.length == 1) return integer;
return digital_root(
chars.map(char => parseInt(char))
.reduce((sum, digit) => sum + digit)
);
}
console.log(digital_root(456));