从递归进行迭代
问题描述:
我有递归函数:从递归进行迭代
public static int fRek(int n) {
if (n <= 0)
return 1;
else if (n == 1)
return 2;
else
return 3 * fRek(n-2)-3;
}
问题:我怎么能写在迭代?循环? 我有这样的:
public static int fIter(int a) {
int b = 1 ;
if (a <= 0) return 1;
else if (a == 1) return 2;
for (int i = 1; i <= a; i = i+2) {
b = b * 3;
b = b - 3;
}
return b;
}
}
但它适用于只是连号:A = 4,6,8,... 为奇数它不正常工作,我不知道为什么
答
是循环,虽然在这种情况下它不是那么容易,因为函数不是尾递归。
让我们先把它转换成一个尾递归函数。为此,我们传递注意到临时结果如何必须经常去通过最后的功能x => 3*x-3
参数:
public static int fRek1(int n, int count) {
if (n <= 0) return finalf(1, count);
else if (n == 1) return finalf(2, count);
else return fRek(n-2, count+1);
}
public static int fRek(int n) { return fRek1(n, 0); }
public static int finalf(int n, int count) {
while (count > 0) {
n = 3*n-3;
count--;
}
return n;
}
现在,你可能会看到如何fRek1转换上面while循环:只要有块地方更换递归变量n和count得到它们的新值,并将方法体封装在while (true)
中。
答
你的第二个问题仍然试图解决这个递归。你需要将你的逻辑分解成一个While语句。这里是一个开始:
int tmp = n
while (tmp > 1) {
Insert main logic here
}
//Base Cases
if (tmp == 1)
n += 3
if (tmp <= 0)
n += 0 //This does nothing but listing for illustration
return n;
答
对于偶数你的第二个算法是行不通的,因为,在第一段代码,该函数返回2
如果n == 1
:
else if (n == 1)
return 2;
,并在你的第二个算法,如果输入参数a
是奇数,for循环会最终将其减少到1
而不是0
,因此使用b=1
进行计算是不正确的。在a
为奇数的情况下应该使用b=2
,在a
为偶数的情况下使用b=1
。
此外,你应该使用从i=1
的for循环,而a
是奇数和i=2
而a
是偶数。
答
它适用于偶数的原因是因为您在函数的开始处对相应的停止条件进行了硬编码。
看看你的递归函数。如果数字是偶数,则会有递归调用,直到n == 0
;也就是说,直到我们到达这里:
if (n <= 0)
return 1;
从那里,我们计算最终结果自下而上。
return 3 * 1 -3; //that's 0
return 3 * 0 -3; //that's -3
return 3 * -3 -3; //that's -12
return 3 * 3 -3; //that's -39
//...and so on
在壳体的数量是奇数,我们从2开始,因为这条线的:
else if (n == 1)
return 2;
从那里,我们计算最终结果自下而上。
return 3 * 2 -3; //that's 3
return 3 * 3 -3; //that's 6
return 3 * 6 -3; //that's 15
return 3 * 15 -3; //that's 42
//... and so on
您的迭代函数像这样开始。
int b = 1 ;
也就是说,你要强加一个条件,只有在数量是偶数的情况下才有。相反,你应该测试数字是偶数还是奇数。
if (a % 2 == 0)
b = 1;
else
b = 2;
for (int i = b; i <= a; i = i+2) {
//...
}
试一下吧。如果你发现任何问题回来并描述它们。 – broncoAbierto