Javascript 如何将中的嵌套循环转换为递归?
我想在递归中转换这个嵌套循环。我如何做到这一点Javascript 如何将中的嵌套循环转换为递归?,javascript,loops,recursion,Javascript,Loops,Recursion,我想在递归中转换这个嵌套循环。我如何做到这一点 for(let i = 0; i < 5; i++) { for(let j = 0; j < 5; j++) { console.log(i,j); } } for(设i=0;i=极限[i]){ r[i]=0; r[i+1]=(r[i+1]| | 0)+1; } 返回r; }, [1]); 如果(values.length>limit.length){ 回来 } iter(限值); } 国际热核实验堆([2,3]);
for(let i = 0; i < 5; i++) {
for(let j = 0; j < 5; j++) {
console.log(i,j);
}
}
for(设i=0;i<5;i++){
for(设j=0;j<5;j++){
控制台日志(i,j);
}
}
这是另一种选择
这种方法使用带有逗号运算符的param初始化(只是为了缩短代码)
此外,还提供了一个操作符param(回调),用于为每次迭代执行任何逻辑
函数循环(n,运算符,i=0,j=0){//Param初始化。
如果(j==n)(j=0,i++);//逗号运算符。
如果(i==n)返回;
操作员(i,j);
循环(n,运算符,i,++j);
}
循环(5,(i,j)=>console.log(i,j))代码>
。作为控制台包装{max height:100%!important;top:0;}
您可以通过获取深度和要迭代的值来递归:
function loop(start, end, depth, exit, ...args){
for(let i = start; i < end; i++)
depth ? loop(start, end, depth - 1, exit, ...args, i) : exit(...args, i);
}
唯一真正的用例是更深的循环,例如
如果您希望完全不使用,请执行以下操作:
const range = (start, end, cb) =>
(cb(start), start + 1 >= end || range (start + 1, end, cb));
function loop(start, end, depth, exit, ...args){
range(start, end, i =>
depth ? loop(start, end, depth - 1, exit, ...args, i) : exit(...args, i));
}
我不建议这样做,但您可以执行以下操作(因为它很难阅读,为了可读性和可理解性,您的代码是最好的)
循环函数(i,j){
如果(j==0){
如果(i!==0)
forLoop(i-1,4);
控制台日志(i,j);
}
否则{
forLoop(i,j-1);
控制台日志(i,j);
}
}
forLoop(4,4)代码>这里是这种递归的另一个示例:
function loop(i,j,limitI,limitJ){
if(i>=limitI) return;
if(j>=limitJ) loop(i+1,0,limitI,limitJ);
else{
console.log(i,j);
loop(i,j+1,limitI,limitJ)
}
}
loop(0,0,4,4);
这是我的表演:
嵌套函数(i,j,maxI,maxJ){
如果(i==maxI)返回
控制台日志(i,j)
if(i
建议的解决方案
function recurse(arg1=0, arg2=0, cb) {
if ( arg2 <= 5 ) {
let _l = arg2++;
if ( arg1 === 5 )
return ;
if ( ++_l === 6 ) {
arg2 = 0;
cb(arg1++, arg2);
recurse(arg1, arg2, cb);
} else {
cb(arg1, arg2 - 1);
recurse(arg1, arg2, cb);
}
}
}
recurse( 0 , 0 , (i,j) => console.log(i,j));
函数递归(arg1=0,arg2=0,cb){
if(arg2 console.log(i,j));
可以使用数组来表示限制和值。顺序相反,因为最低索引先递增
这适用于嵌套循环的任意计数,并允许使用任意的最大值限制
函数iter(limit,values=limit.map(=>0)){
console.log(values.join(“”));
值=值。减少((r,v,i)=>{
r[i]=(r[i]| | 0)+v;
如果(r[i]>=极限[i]){
r[i]=0;
r[i+1]=(r[i+1]| | 0)+1;
}
返回r;
}, [1]);
如果(values.length>limit.length){
回来
}
iter(限值);
}
国际热核实验堆([2,3]);
.as控制台包装器{max height:100%!important;top:0;}
通用函数产品
计算其输入值-如果您的环境中尚未填充,则可以使用多边形填充
Array.prototype.flatMap=函数(f,上下文)
{
返回此.reduce((acc,x)=>acc.concat(f(x)),[])
}
常量乘积=(第一个=[],…剩余)=>
{
常量循环=(梳状,第一,…剩余)=>
rest.length==0
?first.map(x=>[…comb,x])
:first.flatMap(x=>loop([…comb,x],…rest))
返回循环([],第一,…剩余)
}
常服=
['♤', '♡', '♧', '♢']
警衔=
['A','2','3','4','5','6','7','8','9','10','J','Q','K']
用于(产品(等级、套装)的const卡)
console.log(卡)
//[‘A’,'♤' ]
//[‘A’,'♡' ]
//[‘A’,'♧' ]
//[‘A’,'♢' ]
// [ '2', '♤' ]
// ...
//[‘Q’,'♧' ]
//[K','♤' ]
//[K','♡' ]
//[K','♧' ]
//[K','♢' ]代码>这里是一个“,”的概要,其中“序列的每个进一步的项…被定义为前面项的函数。”
您可能知道,递归函数通常至少有一个基本情况,即终止递归,以及至少一个递归调用。要找到模式,让我们检查序列:
0,0
0,1
0,2
0,3
0,4
1,0
1,2
...
对前面参数的调用终止的基本情况似乎是0,0
。但这也是控制台日志开始的地方,这意味着我们必须首先调用所有基本情况。为了方便起见,假设函数需要正参数:
function f(i, j){
if (i == 0 && j == 0){
console.log(i,j);
return;
}
}
我们还可以注意到,对于j
s的每个周期,i
外环保持不变:
function f(i, j){
if (i == 0 && j == 0){
console.log(i,j);
return;
}
if (j == 0)
// ... what happens here?
}
但是这里我们陷入了困境。当j
大于零时,我们可以确定当前项来自f(i,j-1)
,但是如果j
在当前项中为零,我们无法确定它在前一项中是什么。我们还需要一个参数:
函数f(i,j,jj){
如果(i==0&&j==0){
控制台日志(i,j);
回来
}
如果(j==0)
f(i-1,jj,jj);
其他的
f(i,j-1,jj);
控制台日志(i,j);
}
f(4,4,4);
将嵌套的for循环转换为其递归对应循环非常困难。问得好
您可以将每个循环(无堆栈)转换为尾部递归算法。因此,对于嵌套循环,此规则也应适用
我认为我们需要两个不同的函数来获得与两个嵌套循环等价的东西:
const循环=([i,j],[k,l])=>{
常量循环=(k,l)=>{
如果(k_>=l_)返回;
否则{
console.log(i,k_);
循环(k+1,l);
}
};
如果(i>=j)返回;
否则{
环(k,l);
环([i+1,j],[k,l]);
}
};
循环([0,5],[0,5]);
为什么?你甚至连一行代码都拿不到?我在学习递归,所以想弄清楚。这么多答案,但没有被接受或赞成票…@没完没了,选一个最通用的或你喜欢的。不应该来自我,但DhruvAs总是很出色:)我认为使用映射(和减少),虽然它允许您演示的更复杂的递归结构,但实际上是一个隐式的for
循环,它并没有真正回答如何将一个循环转换为递归的问题。但是,如果您还定义了递归映射
和减少
,那么就可以了:)我想“将for循环转换为递归”意味着答案不包括for循环:)他说的是嵌套的for循环..我不认为带有re的循环
function f(i, j){
if (i == 0 && j == 0){
console.log(i,j);
return;
}
if (j == 0)
// ... what happens here?
}