I am getting RangeError: Maximum call stack size exceeded error in Javascript
I am getting RangeError: Maximum call stack size exceeded error in Javascript
我正在尝试通过递归解决 leetcode 的问题,但我收到一条错误消息说 RangeError: Maximum call stack size exceeded
也许我做错了什么。
问题:
编写一个算法来确定数字 n 是否快乐。
快乐号码是由以下过程定义的号码:
从任何正整数开始,将数字替换为其数字的平方和。
重复这个过程直到数字等于1(它会停留在那里),或者它在一个不包括1的循环中无限循环。
此过程以 1 结尾的那些数字是快乐的。
Return 如果 n
是一个快乐的数字,则为真,否则为 false
。
Example 1:
Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
Example 2:
Input: n = 2
Output: false
我的代码:
var isHappy = function(n) {
if(n.length<2) return false
var fn=(n)=>{
let i=0;
let sum=0;
while(i<n.length){
sum=sum+Math.pow(n[n.length-1-i],2);
i++;
}
while(sum!==1){
//console.log(sum)
fn(sum);
}
if(sum === 1) return true
}
fn(n)
};
PS: 我不需要这个问题的解决方案。我想找出为什么我的代码不起作用以及我做错了什么。而且,我应该做哪些更改才能正常工作。
Link到上面的问题
Maximum call stack size exceeded
当函数调用其他函数的次数过多时会出现此错误。在这种情况下,如果数字是一个“不快乐”的数字,您的函数将无休止地递归调用自身。
考虑在你的函数中添加一些东西,让你知道进程是否无限循环。
考虑使用 arguments/arrays 来存储已经出现的数字。
正如您自己所写,“重复该过程,直到数字等于 1(它将停留在该位置),或者它无限循环 一个循环”。 =34=].
在您的实现中,fn
无限调用自身。在此过程中,javascript 虚拟机在每次迭代时都会在内存中创建一个函数上下文。这可以在特定时间完成,之后错误 Maximum call stack size exceeded
抛出。
我做错了什么?
当你找到一个快乐的数字时,你 return 为真,否则你永远不会 return 为假。添加一个条件来检测不满意的数字(检测一个循环),在这种情况下 return false。
编辑:这是一个示例实现:
var isHappy = function(n) {
if(n.length<2) return false
// placeholder to store already called values
const calledValues= new Set()
var fn=(n)=>{
let i=0;
let sum=0;
if (calledValues.has(n))
// cycle detected!
return false;
calledValues.add(n);
while(i<n.length){
sum=sum+Math.pow(n[n.length-1-i],2);
i++;
}
if (sum !== 1)
return fn(sum.toString());
else
// sum === 1, number is happy!
return true
}
// make sure to pass a string to fn
return fn(n.toString());
};
(new Array(20)).fill().map((_,i)=>10+i)
.forEach(n=> console.log(n, "is happy?", isHappy(n)));
我正在尝试通过递归解决 leetcode 的问题,但我收到一条错误消息说 RangeError: Maximum call stack size exceeded
也许我做错了什么。
问题:
编写一个算法来确定数字 n 是否快乐。
快乐号码是由以下过程定义的号码:
从任何正整数开始,将数字替换为其数字的平方和。
重复这个过程直到数字等于1(它会停留在那里),或者它在一个不包括1的循环中无限循环。 此过程以 1 结尾的那些数字是快乐的。
Return 如果 n
是一个快乐的数字,则为真,否则为 false
。
Example 1:
Input: n = 19
Output: true
Explanation:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1
Example 2:
Input: n = 2
Output: false
我的代码:
var isHappy = function(n) {
if(n.length<2) return false
var fn=(n)=>{
let i=0;
let sum=0;
while(i<n.length){
sum=sum+Math.pow(n[n.length-1-i],2);
i++;
}
while(sum!==1){
//console.log(sum)
fn(sum);
}
if(sum === 1) return true
}
fn(n)
};
PS: 我不需要这个问题的解决方案。我想找出为什么我的代码不起作用以及我做错了什么。而且,我应该做哪些更改才能正常工作。
Link到上面的问题
Maximum call stack size exceeded
当函数调用其他函数的次数过多时会出现此错误。在这种情况下,如果数字是一个“不快乐”的数字,您的函数将无休止地递归调用自身。
考虑在你的函数中添加一些东西,让你知道进程是否无限循环。
考虑使用 arguments/arrays 来存储已经出现的数字。
正如您自己所写,“重复该过程,直到数字等于 1(它将停留在该位置),或者它无限循环 一个循环”。 =34=].
在您的实现中,fn
无限调用自身。在此过程中,javascript 虚拟机在每次迭代时都会在内存中创建一个函数上下文。这可以在特定时间完成,之后错误 Maximum call stack size exceeded
抛出。
我做错了什么?
当你找到一个快乐的数字时,你 return 为真,否则你永远不会 return 为假。添加一个条件来检测不满意的数字(检测一个循环),在这种情况下 return false。
编辑:这是一个示例实现:
var isHappy = function(n) {
if(n.length<2) return false
// placeholder to store already called values
const calledValues= new Set()
var fn=(n)=>{
let i=0;
let sum=0;
if (calledValues.has(n))
// cycle detected!
return false;
calledValues.add(n);
while(i<n.length){
sum=sum+Math.pow(n[n.length-1-i],2);
i++;
}
if (sum !== 1)
return fn(sum.toString());
else
// sum === 1, number is happy!
return true
}
// make sure to pass a string to fn
return fn(n.toString());
};
(new Array(20)).fill().map((_,i)=>10+i)
.forEach(n=> console.log(n, "is happy?", isHappy(n)));