我在大学里有个作业,要用C ++编写一个递归函数,该函数可以找到数组或整数中最长的连续递增子数组的长度。另外,我有一个代码框架,必须将其用于我的代码,并且该函数不得包含循环和更多函数。
例如,对于数组1,2,4,6,4,21,21,22,0,1,3,5,100,7 结果将为5(因为0到100是5个数字)。
骨骼是:
#include <stdio.h>
#define MAX_SIZE 1000
int get_max_series(int a[], int size);
int main() {
int i, size_array, array[MAX_SIZE];
scanf("%d", &size_array);
for (i = 0; i < size_array; i++)
scanf("%d", &array[i]);
printf("%d", get_max_series(array, size_array));
return 0;
}
int get_max_series(int a[], int size) {
// My code should be here
}
我已经成功编写了一个计算递增对数的函数,但是当计数对下降时却无法重置计数器。代码如下:
#include <stdio.h>
#define MAX_SIZE 1000
int get_max_series(int a[], int size);
int main() {
int i, size_array, array[MAX_SIZE];
scanf("%d", &size_array);
for (i = 0; i < size_array; i++)
scanf("%d", &array[i]);
printf("%d", get_max_series(array, size_array));
return 0;
}
int get_max_series(int a[], int size) {
if (size == 1)
return 1;
if (a[0] < a[1])
return 1 + get_max_series(&a[1], size - 1);
return get_max_series(&a[1], size - 1);
}
我很乐意获得一些建议,以使我的代码在这种情况下可以正常工作,或者完全更改代码。 谢谢!
答案 0 :(得分:2)
这是一个似乎遵循您的规则的O(n)例程(变量名称应有助于解释发生的情况):
#include <stdio.h>
#define MAX_SIZE 1000
int get_max_series(int a[], int size);
int main() {
int i, size_array, array[MAX_SIZE];
scanf("%d", &size_array);
for (i = 0; i < size_array; i++)
scanf("%d", &array[i]);
printf("%d", get_max_series(array, size_array));
return 0;
}
int get_max_series(int a[], int size) {
int i = size - 1;
if (i < 2){
if (a[1] > a[0])
return a[0] = 2;
else
return a[0] = 1;
}
int max = get_max_series(a, i);
int max_up_to_i = a[i - 2];
if (a[i] > a[i - 1]){
a[i - 1] = 1 + max_up_to_i;
if (a[i - 1] > max)
max = a[i - 1];
} else {
a[i - 1] = 1;
}
return max;
}
答案 1 :(得分:1)
如果您不想使用静态/全局变量或辅助函数,则可以对大小大于1的数组使用以下缩减形式(尽管这样做很慢,因为它会进行两次递归调用):
如果a[0]>=a[1]
,则我们不能在最大升序子数组中包含a[0]
,因为它违反了我们的升序概念,因此我们像在代码中一样返回get_max_series(a + 1,size-1)。
在a[0]<a[1]
时,我们有两种情况:
如果get_max_series(a+1,size-1)==size-1
,则整个子数组a [1],...,a [size-1]递增。这意味着a [0],a [1],...,a [size-1]也在上升,因此在这种情况下我们可以返回1 + get_max_series(&a[1], size-1)
。
如何,如果get_max_series(a+1,size-1)!=size-1
表示子数组a [1],...,a [size-1]没有升序,则最大子数组不能同时包含两个[1]和a [size-1](由于连续性,它必须包括介于两者之间的所有内容,这会使它不升序)。
因此,您返回max(1+get_max_series(&a[0], size-1), get_max_series(&a[1], size-1))
。
请注意,这里您对get_max_series进行了两次调用,因此您的计算成本会迅速增长(基本上与执行fibonacci函数的朴素递归实现时出现的效率低下相同)。
该功能类似于
int get_max_series(int a[], int size) {
if (size <= 1)
return size;
int max_sub = get_max_series(&a[1], size - 1);
if (a[0] >= a[1])
return max_sub;
else{
if (max_sub==(size-1))
return size;
else
return std::max(get_max_series(&a[0], size-1), max_sub);
}
}
我在这里使用std::max
,但是如果您不想使用algorithm
库,则可以使用if-else查找最多两个数字。
答案 2 :(得分:-1)
最长的升序子数组不一定从数组的开头开始。因此,
return 1 + get_max_series(&a[1], size - 1);
不正确。我看不到如何仅依靠检查一个字符(至少在给定签名内)来挽救这种方法。考虑在数组的开头找到最长的升序,然后沿着以下行递归到其余序列:
int get_max_series(int a[], int size)
{
int n = get_longest_acsending_prefix(a, size);
if (n == size)
return n;
return max(n, get_longest_ascending_prefix(a + n, size - n));
}
也就是说,我在这里看不到递归点。