C中偶数数组的递归
Recursion for even array in C
我知道这里甚至有很多关于递归的问题,但我不知道在 C 中它是我的逻辑还是我的语法错误(或者可能两者都是错误的),因为据我所知我可能需要指针。特别是当我在 C 中使用函数时,所以我很难找到任何我作为 cs 本科生新生可以理解的问题。
所以我的任务是简单地创建一个数组,其中包含在输入中确定的范围内的偶数,如果输入 n = 10
,则该数组需要包含 [0, 2, 4, 6, 8, 10]
,如果 n = 9
,则该数组将只是 [0, 2, 4, 6, 8]
。但是我必须用递归来做,我不知道我的代码有什么问题,因为输出有点奇怪。
#include <stdio.h>
int even(int x, int arrEven[]) {
if (x == 0) {
arrEven[0] = 0;
return 0;
}
else if (x > 0) {
arrEven[x - 1] = even(x - 2, arrEven) + 1;
return arrEven[x - 1];
}
}
int main(void) {
printf("n = ");
int n;
scanf("%d", &n);
n = (n / 2) + 1;
int arrEven[n];
even(n, arrEven);
for (int i = 0; i < (n - 1); i++) {
printf("%d, ", arrEven[i]);
}
printf("%d", arrEven[n - 1]);
}
当我输入 10
时,输出是
0, 1, -731908444, 2, 781232032, 3
而不是
0, 2, 4, 6, 8, 10
您混合使用一个变量用于两个目的。
在您的代码中,n
用作数组中的索引,同时用作要放入数组中的值。
有很多选择可以做到这一点。可能看起来像这样:
#include <stdio.h>
void even(int *arrEven, int value, int limit) {
*arrEven = value;
if (value < limit) {
even(arrEven+1, value+2, limit);
}
}
int main (void) {
int limit;
int count;
printf("n = ");
scanf("%d", &limit);
// TODO: Check return value.
if (limit < 0)
{
fprintf(stderr, "Only non-negative limits are allowed.\n");
exit(-1);
}
count = (limit / 2) + 1;
int arrEven[count];
even(arrEven, 0, limit);
for (int i = 0; i < count-1; i++){
printf("%d, ", arrEven[i]);
}
printf("%d\n", arrEven[count-1]);
}
我想你想要的是这样的:
int even(int x, int arrEven[])
{
if (x == 0)
return 0;
arrEven[x - 1] = even(x - 1, arrEven);
return arrEven[x - 1] + 2;
}
这里x
纯粹是数组索引,只有偶数值进入数组的事实是由2
添加到[=13=返回的值这一事实处理的] 以及返回 0
.
的终止条件
您的递归函数只初始化目标数组的一半,因为在 arrEven[x - 1] = even(x - 2, arrEven) + 1;
中您将 x
递减 2
,而不是将值递增 2
。您可以这样修复您的代码:
int even(int x, int arrEven[]) {
if (x == 0) {
arrEven[0] = 0;
return 0;
} else
if (x > 0) {
arrEven[x - 1] = even(x - 1, arrEven) + 2;
return arrEven[x - 1];
}
}
但是请注意,上面的代码不使用尾递归,并且需要与 x
成比例的堆栈深度。这是一个替代方案,其中递归仅在从函数返回之前发生:
void even(int n, int arrEven[]) {
if (n > 0) {
errEven[n - 1] = 2 * (n - 1);
even(n - 1, arrEven);
}
}
以上函数应编译为与等效迭代版本类似的可执行代码:
void even(int n, int arrEven[]) {
while (n > 0) {
n = n - 1;
errEven[n] = 2 * n;
}
}
我知道这里甚至有很多关于递归的问题,但我不知道在 C 中它是我的逻辑还是我的语法错误(或者可能两者都是错误的),因为据我所知我可能需要指针。特别是当我在 C 中使用函数时,所以我很难找到任何我作为 cs 本科生新生可以理解的问题。
所以我的任务是简单地创建一个数组,其中包含在输入中确定的范围内的偶数,如果输入 n = 10
,则该数组需要包含 [0, 2, 4, 6, 8, 10]
,如果 n = 9
,则该数组将只是 [0, 2, 4, 6, 8]
。但是我必须用递归来做,我不知道我的代码有什么问题,因为输出有点奇怪。
#include <stdio.h>
int even(int x, int arrEven[]) {
if (x == 0) {
arrEven[0] = 0;
return 0;
}
else if (x > 0) {
arrEven[x - 1] = even(x - 2, arrEven) + 1;
return arrEven[x - 1];
}
}
int main(void) {
printf("n = ");
int n;
scanf("%d", &n);
n = (n / 2) + 1;
int arrEven[n];
even(n, arrEven);
for (int i = 0; i < (n - 1); i++) {
printf("%d, ", arrEven[i]);
}
printf("%d", arrEven[n - 1]);
}
当我输入 10
时,输出是
0, 1, -731908444, 2, 781232032, 3
而不是
0, 2, 4, 6, 8, 10
您混合使用一个变量用于两个目的。
在您的代码中,n
用作数组中的索引,同时用作要放入数组中的值。
有很多选择可以做到这一点。可能看起来像这样:
#include <stdio.h>
void even(int *arrEven, int value, int limit) {
*arrEven = value;
if (value < limit) {
even(arrEven+1, value+2, limit);
}
}
int main (void) {
int limit;
int count;
printf("n = ");
scanf("%d", &limit);
// TODO: Check return value.
if (limit < 0)
{
fprintf(stderr, "Only non-negative limits are allowed.\n");
exit(-1);
}
count = (limit / 2) + 1;
int arrEven[count];
even(arrEven, 0, limit);
for (int i = 0; i < count-1; i++){
printf("%d, ", arrEven[i]);
}
printf("%d\n", arrEven[count-1]);
}
我想你想要的是这样的:
int even(int x, int arrEven[])
{
if (x == 0)
return 0;
arrEven[x - 1] = even(x - 1, arrEven);
return arrEven[x - 1] + 2;
}
这里x
纯粹是数组索引,只有偶数值进入数组的事实是由2
添加到[=13=返回的值这一事实处理的] 以及返回 0
.
您的递归函数只初始化目标数组的一半,因为在 arrEven[x - 1] = even(x - 2, arrEven) + 1;
中您将 x
递减 2
,而不是将值递增 2
。您可以这样修复您的代码:
int even(int x, int arrEven[]) {
if (x == 0) {
arrEven[0] = 0;
return 0;
} else
if (x > 0) {
arrEven[x - 1] = even(x - 1, arrEven) + 2;
return arrEven[x - 1];
}
}
但是请注意,上面的代码不使用尾递归,并且需要与 x
成比例的堆栈深度。这是一个替代方案,其中递归仅在从函数返回之前发生:
void even(int n, int arrEven[]) {
if (n > 0) {
errEven[n - 1] = 2 * (n - 1);
even(n - 1, arrEven);
}
}
以上函数应编译为与等效迭代版本类似的可执行代码:
void even(int n, int arrEven[]) {
while (n > 0) {
n = n - 1;
errEven[n] = 2 * n;
}
}