在javascript中将循环函数转换为递归函数
我试图自学如何编写递归函数,有人建议尝试将循环转换为递归。因此,我尝试将第一个for循环函数更改为递归函数。这是我的密码:在javascript中将循环函数转换为递归函数,javascript,function,loops,recursion,tail-recursion,Javascript,Function,Loops,Recursion,Tail Recursion,我试图自学如何编写递归函数,有人建议尝试将循环转换为递归。因此,我尝试将第一个for循环函数更改为递归函数。这是我的密码: // Function that uses for loop. function onlyOne(value1, value2, value3) { var array = [value1, value2, value3]; var count = 0; for(var i = 0; i < array.length; i++) {
// Function that uses for loop.
function onlyOne(value1, value2, value3) {
var array = [value1, value2, value3];
var count = 0;
for(var i = 0; i < array.length; i++) {
if(!!array[i] === true) {
count ++;
}
} if(count === 1) {
return true;
} else {
return false;
}
}
// Function that uses recursion.
function onlyOne2(a, b, c) {
var array = [a, b, c];
var count = 0;
var numTrue = 0;
if(!!array[count] === true) {
numTrue++;
}
if(count === array.length-1) {
if(numTrue === 1) {
return true;
} else {
return false;
}
}else {
count++;
return onlyOne2(a, b, c);
}
}
console.log(onlyOne2(true, false, false));
//用于循环的函数。
仅限一个函数(值1、值2、值3){
变量数组=[value1,value2,value3];
var计数=0;
对于(var i=0;i
每个函数的目的都是在只有一个参数为真时返回真。否则,函数返回false。for循环函数工作正常。然而,当我使用递归函数时,我得到了一个错误:超过了最大调用堆栈大小。我想知道我做错了什么。谢谢你的帮助 上述代码的问题是,每当函数递归时,再次声明
count
和numTrue
并因此发生无限循环,以下是正确的代码(声明count
和numTrue
为全局:
var计数=0;
var numTrue=0;
功能仅限2(a、b、c){
var数组=[a,b,c];
如果(!!数组[计数]==真){
numTrue++;
}
if(count==array.length-1){
如果(numTrue==1){
返回true;
}否则{
返回false;
}
}否则{
计数++;
仅返回2(a、b、c);
}
}
log(仅限2(真、假、假));
您的方法存在一些问题
直接使用布尔值:if(!!数组[i]==true)
if(数组[i])
true
值true
if (count === 1) { // <- Use this comparison to return the specific value.
return true;
^
} else {
return false;
^
}
您必须使用索引i
看看这个带有这些修复的代码片段
//用于循环的函数。
仅限一个函数(值1、值2、值3){
变量数组=[value1,value2,value3];
var计数=0;
对于(var i=0;i console.log(onlyOne2(true,false,false,0,0));
这很有趣。好的,如果数组中正好有一个项是truthy,那么我们有一个函数返回true。让我们考虑递归中的基本要求
基本情况下,数组为空:
if (!array.length)
return false;
基本情况下,数组中只有一个元素:
if (array.length == 1)
return !!array[0] === true
否则:
let next = f(rest-of-array)
if (!!array[0] === true)
return !next
else
return next
JavaScript代码:
函数f(arr,i){
//与!array.length相同
如果(i==arr.length)
返回false;
//与array.length==1相同
如果(i==arr.length-1)
返回!!arr[i]
//与f相同(数组的其余部分)
设next=f(arr,i+1)
如果(!!arr[i])
回来!下一个
下一个返回
}
输出:
f([undefined,2,0],0)
=>正确
f([1,2,未定义],0)
=>错误
f([undefined,false,1],0)
=>正确
f([5,false,false],0)
=>正确
您可以为想要的值和递归函数使用计数器
它可以处理任意数量的参数
function onlyOne(a,b,c){
let arr = Array.from(arguments);
let count = 0;
let item = arr.shift();
if(true === item){
++count;
}
if(arr.length > 0) {
count += onlyOne.apply(this,arr);
return count == 1;
}
return count;
}
仅功能(计数、v、…剩余){
如果(v){//检查值
如果(!count){//检查计数为零
return false;//因为发现比需要的更真实
}
计数--;//递减计数
}
如果(!rest.length){//请检查长度是否为零
return!count;//return not count
}
仅返回(count,…rest);//带有count和rest的尾部调用
}
log(仅(1,false,false,false));//false
log(仅(1,false,false,true));//true
log(仅(1,false,true,false));//true
log(仅(1,false,true,true));//false
log(仅(1,真,假,假));//真
log(仅(1,真,假,真));//假
console.log(仅(1,真,真,假));//假
log(仅(1,true,true,true));//false
console.log('----');
log(仅(2,false,false,false));//false
log(仅(2,false,false,true));//false
log(仅(2,false,true,false));//false
log(仅(2,false,true,true));//true
log(仅(2,真,假,假));//假
log(仅(2,true,false,true));//true
log(仅(2,true,true,false));//true
console.log(仅(2,true,true,true));//false
。作为控制台包装{max height:100%!important;top:0;}
您可以将任何for
循环转换为递归:
let a=0, b=1,
for (let n=5; n > 0; n--) {
const tmpa = a;
a = b;
b += tmpa;
}
function onlyOne(arr) {
function iterate (index, count) {
if (index < len && count <= 1) {
return iterate(
index + 1,
count + (array[index] ? 1 : 0)
);
}
return count;
}
const len = array.length; // cache
const count = iterate(0, 0);
return count === 1;
}
此处a
b
和n
发生变化,原因是a
值具有第6个斐波那契数。因此,我们将其设为参数并返回:
function forLoop(n, a, b) {
if(n > 0) {
return forLoop(n - 1, b, a + b);
}
return a;
}
const a = forLoop(5, 0, 1);
因此,对于使用for
循环的函数:
function onlyOne(value1, value2, value3) {
const array = [value1, value2, value3];
let count = 0;
for(var i = 0; i < array.length; i++) {
if(!!array[i] === true) {
count ++;
}
}
if(count === 1) {
return true;
}
return false;
}
由于您只有3个元素,这可能已经足够好了,但是假设您想要为一个数组实现类似的功能,您应该计划以已知的速度返回。在for
版本中,它将如下所示:
function onlyOne(arr) {
let count = 0;
const len = array.length; // cache
for (index = 0; index < len; index++) {
if (arr[index]) {
count++;
if(count > 1) return false; // early return
}
}
return count === 1;
}
仅限一个函数(arr){
让计数=0;
const len=array.length;//缓存
为了
function onlyOne(arr) {
function iterate (index, count) {
if (index < len && count <= 1) {
return iterate(
index + 1,
count + (array[index] ? 1 : 0)
);
}
return count;
}
const len = array.length; // cache
const count = iterate(0, 0);
return count === 1;
}
function onlyOne(a,b,c){
let arr = Array.from(arguments);
let count = 0;
let item = arr.shift();
if(true === item){
++count;
}
if(arr.length > 0) {
count += onlyOne.apply(this,arr);
return count == 1;
}
return count;
}