int smallest(int arr[],int i,int small,int n)
{
if(i==n)
return small;
else if(small>=arr[i])
{
smallest(arr,i+1,arr[i],n);
}
}
所以编译器说控件到达非void函数的结尾。有什么建议吗?
答案 0 :(得分:1)
重写它,这样你就不会在没有返回任何东西的情况下掉出函数的末尾; e.g。
int smallest(int arr[],int i,int small,int n)
{
if (i == n)
return small;
else if(small >= arr[i])
return smallest(arr, i+1, arr[i], n);
else
return smallest(arr, i+1, small, n);
}
您也可能希望提供一个替代且更简单的调用,以便调用用户代码进行所需的初始化,在这种情况下,您可能希望将上述内容重命名为basic_smallest
,然后创建一个新函数< / p>
#include <limits.h>
int smallest(int arr[], int i)
{
return basic_smallest(arr, i, INT_MAX, 0);
}
另外,请记住,像这样的递归实现会让您面临为大型阵列炸毁堆栈的风险。非递归实现可能更安全:
int smallest(int arr[], int i)
{
int n;
int small;
for(n = 0 ; n < i ; ++n)
small = (small >= arr[n] ? arr[n] : small);
return small;
}
答案 1 :(得分:1)
您在逻辑流程中错过了两个返回案例,并且您正在努力使其变得比它无论如何更难。
关于两个缺失的退货声明,请注明以下内容:
int smallest(int arr[],int i,int small,int n)
{
if(i==n)
return small;
else if(small>=arr[i])
{
smallest(arr,i+1,arr[i],n); // here
}
// and here
}
当您删除无用的else
用法时,这两个都变得更加明显。它不是必需的。如果先前的if
为真,则该函数已退出。
int smallest(int arr[],int i,int small,int n)
{
if(i==n)
return small;
if(small>=arr[i])
smallest(arr,i+1,arr[i],n); // here
// and here
}
同样的问题,但现在它应该在视觉上更明显,实际返回任何内容的唯一地方是i == n
。在下面两种情况下(当small >= arr[i]
为真或假时)都是提供的任何返回值。
然后,如果保留现有接口,则解决方案是添加返回AND最终大小写,从而覆盖所有逻辑路径以使其可达return
:
int smallest(int arr[],int i,int small,int n)
{
if(i==n)
return small;
if(small>=arr[i])
return smallest(arr,i+1,arr[i],n);
return smallest(arr,i+1,small,n); // note small. it's important
}
不同的方法
递归smallest()
只能使用序列地址和长度。您不需要标记small
值,也不需要围绕该索引进行标记。相反,您可以简单地使用指针算法来移动基本序列地址,直到耗尽给定元素,同时调整最终告诉我们需要停止递归的剩余序列长度。所有相关数据都已在递归堆栈中保留给您;你只需要知道如何使用它:
int smallest(const int arr[], size_t len)
{
if (len < 2) // 1
return *arr;
int small = smallest(arr+1, len-1); // 2
return (*arr < small ? *arr : small); // 3
}
以下注意点的说明
len < 2
为真,则只返回序列开头的任何内容。我遗漏了一个缺乏迂腐的步骤。可以想象有人可以传递一系列零长度,如果是这种情况,则应将其视为运行时错误。如果这是除了练习之外的任何事情(它看起来像是),请记住这一点。*arr
的基本元素后面的元素的最小值。请注意,arr+1
是第一个参数。这意味着递归调用将引用序列中的 next 元素作为 base 元素(*arr
)。另请注意len-1
,注意现在序列中剩余的元素少了一个。一旦序列耗尽,我们依赖于从上面的(1)触发基本情况,我们需要停止递归。示例运行如下所示:
#include <iostream>
#include <random>
#include <utility>
#include <stdio.h>
int smallest(const int arr[], size_t len)
{
if (len < 2)
return *arr;
int small = smallest(arr+1, len-1);
return (*arr < small ? *arr : small);
}
int main()
{
int arr[] = { 7,3,5,1,9,2,4,6,8 };
printf("Smallest : %d\n", smallest(arr, sizeof arr / sizeof *arr));
}
<强>输出强>
Smallest : 1