以迭代方式编写递归函数
Writing a recursive function iteratively
我最近才开始学习递归,并且对特定练习有一些麻烦;从递归状态迭代重写函数,特别是如果涉及几种基本情况:
double function(int j, int i)
{
if(i == 0 || j == 1)
{
return 1;
}
if(i == 1 || j == 0)
{
return j;
}
if(i > 0)
{
return j * function(j, --i);
}
return 1 / (function(j, -i))
}
我在迭代重写函数时遇到问题。
首先,这是您的压缩代码(我这样做是为了回答,不要在实际代码中这样做。
double function(int j, int i) {
if(i == 0 || j == 1) return 1;
if(i == 1 || j == 0) return j;
if(i > 0) return j * function(j, --i);
return 1 / (function(j, -i)); //changed this to -i
//might be a division by zero, you should check for that
}
由于最后一个块实际上只能发生在最外层的循环上,因此我们将将其拉出:
double outer_function(int j, int i) {
if (i<0)
return 1 / inner_function(j, -i);
else
return inner_function(j, i);
}
double inner_function(int j, int i) {
if(i == 0 || j == 1) return 1;
if(i == 1 || j == 0) return j;
if(i > 0) return j * inner_function(j, --i);
}
我要做的第一件事是尝试将其转换为尾递归形式。 这涉及重新排列方程,以便在递归之后没有任何内容。(我不是100%确定我做对了这一步)
double inner_function(int j, int i, int times=1) {
if(i == 0 || j == 1) return times;
if(i == 1 || j == 0) return times*j;
return inner_function(j, --i, times*j);
}
现在,由于在每个代码路径中,函数调用后没有代码,因此这是完全尾递归的。 尾递归很容易更改为迭代!
double inner_function(int j, int i, int times=1) {
while(true) {
if(i == 0 || j == 1) return times;
if(i == 1 || j == 0) return times*j;
//return inner_function(j, --i, times*j);
--i;
times *= j;
//go again!
}
}
如果我从这里进行优化:
double function(int j, int i) {
bool invert = false;
if(i<0) {
i=-i;
invert=true;
}
double result=1;
if(i == 0) result = 0;
else if(j == 0) result = j;
else if (j != 1) {
while(i--)
result *= j;
}
return (invert ? 1/result : result);
}
或者,如果我猜到你的意图:
double function(int j, int i) {
return std::pow(double(j), double(i));
}
在递归期间,您实际上只有一个基本情况。 j
永远不会改变,所以一开始只是一个特例。 i
将始终为正数,并在第一次递归调用后朝向 0。所以唯一真正的基本情况是i == 1
.
函数的开头可以保持不变。
double function(int j, int i)
{
if(i == 0 || j == 1) { return 1; }
if(i == 1 || j == 0) { return j; }
现在你只需要处理i > 0
和i < 0
的情况(i == 0
在开始时已经处理好了)。
这两种情况的区别在于,如果i
为负数,则切换符号并反转结果。
int invert = i < 0;
i = abs(i); // or: if (i < 0) { i = -i; }
现在看看递归部分并弄清楚发生了什么。
return j * function(j, --i);
function()
将被调用,直到 i
为 1,此时的结果将是 j
。每次迭代都会将返回值乘以 j
。这可以这样写:
double returnValue = j; // (the i == 1 case)
while (i-- > 1) { // loop while i is greater than 1
returnValue = j * returnValue; // multiply j by the return value
}
现在,如有必要,请反转并返回结果。
if (invert) {
returnValue = 1 / returnValue;
}
return returnValue;
}
相关文章:
- 递归函数计算序列中的平方和(并输出过程)
- 如何在Elixir中调用递归函数并行
- 递归函数有效,但无法记忆
- 为什么我的递归函数按降序打印,然后按升序打印?
- 为什么递归函数的最终输出是 5?
- 有没有办法使用递归函数找到数组中最小值的 INDEX?C++
- 如何将记忆应用于此递归函数?
- 如何从递归函数中完全返回,该函数给出了每个函数结果的累积相加?
- 无穷大而循环时具有递归函数
- 即使没有调用这个递归函数,它是如何工作的?
- 如何使此递归函数从给定的起始位置返回最小的整数?
- 此递归函数的每次迭代的值存储在哪里?
- 可以清除递归函数中的变量吗?
- 如何在递归函数调用中返回当前函数值
- 递归函数 c++ 的复杂性
- 这个递归函数有什么作用?运行时的复杂性是多少?
- 任何人都可以查明我的递归函数中的错误吗?
- 如何编写一个递归函数,以随机的方式混淆从0到6的数字
- 以迭代方式编写递归函数
- 递归函数以某种方式打印