我有一个c ++编程类的作业,用于在不使用静态变量的情况下编写递归函数,使用以下原型: int findmin(const int a [],int n);
我的解决方案适用(对于非常小的数组),但我认为~2 ^ n复杂度过高并且可以改进。
是否可以在指定标准内进行任何改进,以提高效率?
int findmin(const int a[], int n)
{
if(n == 0)
return a[0];
else
{
if(a[n-1] < findmin(a,(n-1)))
return a[n-1];
else
return findmin(a,(n-1));
}
}
答案 0 :(得分:5)
担心效率有点傻,因为在O(n)中有一个明显的,非递归的方式,一次通过。甚至有一个STL算法std :: min_element。但是,这是一个愚蠢的任务。首先要确保您的解决方案是正确的。当n == 0时,a [0]是否有效?通常,这样的#include <algorithm>
#include <cassert>
int findmin(const int a[], int n)
{
assert(n>0);
if(n == 1) // See heyah.
return a[0];
else
{
return std::min(a[0], findmin(a + 1, n - 1));
}
}
表示数组的长度,而不是最低的索引。
要从O [n ^ 2]转到O [n],请务必仅比较每个元素一次。这意味着不会在每次传递时从数组的开头开始。
int findmin(const int a[], int n) {
if(n<=0) { throw std::length_error("findmin called on empty array");}
return *std::min_element(a, a+n);
}
在for-real C ++代码中,如果由于某种原因我们背负旧时尚功能签名,我们会做这样的事情:
{{1}}
答案 1 :(得分:3)
您可以执行条件运算符?:
来删除一堆if else
语句,以使函数更清晰。而不是两次调用findmin()
,你可以将返回值赋给语句中的变量,这是此代码与原始代码的主要优势。
int findmin(const int a[], int n) {
if (n == 0) // base case
return a[0];
return a[n] < (int min = findmin(a, n - 1)) ? a[n] : min;
}
这个(a[n] < (int min = findmin(a, n - 1)) ? a[n] : min;
)也可以使用if语句完成:
if (a[n] < (int min = findmin (a, n - 1))
return a[n];
else
return min;
编辑: 根据许多信誉良好的来源,这是O(n)时间。 O(n ^ 2)将是我们将每个元素与所有其他元素进行比较。