您好我想将此代码转换为递归函数:
int a3(int* a, int length) {
if(a == 0 || length <= 0) return 0;
int sum = 0;
for(int i = 0; i < length; i++) {
for(int j = i; j < length; j++) {
sum += a[j];
}
}
return sum;
}
我的方法是:
int rec_help(int*a, int length);
int a3(int* a, int length) {
if(a == 0 || length <= 0) return 0;
else{
return rec_help(a,length) + rec_help(a+1,length-1) ;
}
}
int rec_help(int*a, int length){
if(a == 0 || length <= 0) return 0;
else{
int tmp = a[0];
return tmp + a3(a+1,length-1);
}
}
但我没有做对。
使用a3()我想模拟第一个for循环,我认为有我的问题:D
使用rec_help()第二个循环和身体,但我在这里混合了一些东西。
我希望得到任何帮助:)
答案 0 :(得分:0)
因为你有2个循环,如果你想要你的函数是递归的,你将需要2个递归函数,一个用于完成第一个循环的工作,另一个用于完成第二个循环的工作... < / p>
这样的事情应该有效:
int a3_rec(int *a, int length)
{
if (length == 0)
return (0);
return (*a + a3_rec(a + 1, length - 1));
}
int a3_rec_hat(int *a, int length)
{
if (a == 0 || length == 0)
return (0);
return (a3_rec(a, length) + a3_rec_hat(a + 1, length - 1));
}
我希望我能帮助你:)。
答案 1 :(得分:0)
作为一般规则,当您将循环转换为递归时,每个循环都会成为一个函数,并且它使用的任何非局部变量都会成为参数。
您的原始代码是
int a3(int* a, int length) {
if(a == 0 || length <= 0) return 0;
int sum = 0;
for(int i = 0; i < length; i++) {
for(int j = i; j < length; j++) {
sum += a[j];
}
}
return sum;
}
让我们从最里面的循环开始。它使用周围范围内的j
,i
,length
,sum
和a
。
void a3_loop0(int *pj, int length, int *psum, int *a) {
if (*pj < length) {
*psum += a[*pjj];
(*pj)++;
a3_loop0(pj, length, psum, a);
}
}
int a3(int* a, int length) {
if(a == 0 || length <= 0) return 0;
int sum = 0;
for(int i = 0; i < length; i++) {
int j = i;
a3_loop0(&j, length, &sum, a);
}
return sum;
}
这是一个非常文字和机械的翻译。每个可变变量都变成了一个指针(在C ++中你会使用它的引用),这会导致一些丑陋且无功能的代码(好吧,代码不使用惯用的函数风格)。但是它有效,我们可以用同样的方式进入下一个循环:
void a3_loop0(int *pj, int length, int *psum, int *a) {
if (*pj < length) {
*psum += a[*pj];
(*pj)++;
a3_loop0(pj, length, psum, a);
}
}
void a3_loop1(int *pi, int length, int *psum, int *a) {
if (*pi < length) {
int j = *pi;
a3_loop0(&j, length, psum, a);
(*pi)++;
a3_loop1(pi, length, psum, a);
}
}
int a3(int* a, int length) {
if(a == 0 || length <= 0) return 0;
int sum = 0;
int i = 0;
a3_loop1(&i, length, &sum, a);
return sum;
}
从技术上讲,我们现在已经完成了,但我们可以清理一些事情。
我要做的第一件事就是将a
的类型更改为const int *
,因为a3
永远不会修改其任何元素。
我要做的第二件事是将循环变量*pi
/ *pj
提升到它们的函数中;他们并不需要指向其他地方的可变对象。
void a3_loop0(int j, int length, int *psum, const int *a) {
if (j < length) {
*psum += a[j];
a3_loop0(j + 1, length, psum, a);
}
}
void a3_loop1(int i, int length, int *psum, const int *a) {
if (i < length) {
a3_loop0(i, length, psum, a);
a3_loop1(i + 1, length, psum, a);
}
}
int a3(const int *a, int length) {
if (a == 0 || length <= 0) return 0;
int sum = 0;
a3_loop1(0, length, &sum, a);
return sum;
}
这已经简化并缩短了代码。
下一步是从这些辅助函数中实际返回一些东西。目前,他们使用*psum
作为累加器并返回void
。我们可以继续使用累加器但是直接返回结果(而不是通过输出参数),如下所示:
void a3_loop0(int j, int length, int sum, const int *a) {
if (j < length) {
return a3_loop0(j + 1, length, sum + a[j], a);
}
return sum; // this was implicit before; "return sum unchanged"
}
void a3_loop1(int i, int length, int sum, const int *a) {
if (i < length) {
return a3_loop1(i + 1, length, a3_loop0(i, length, sum, a), a);
}
return sum; // ditto
}
int a3(const int *a, int length) {
if (a == 0 || length <= 0) return 0;
return a3_loop1(0, length, 0, a);
}
此版本的代码“纯粹是功能性的”,因为它永远不会修改任何变量;它只传递函数和从函数返回值。
如果我们愿意,我们可以删除所有if
语句并将所有内容写为表达式:
void a3_loop0(int j, int length, int sum, const int *a) {
return j < length
? a3_loop0(j + 1, length, sum + a[j], a)
: sum;
}
void a3_loop1(int i, int length, int sum, const int *a) {
return i < length
? a3_loop1(i + 1, length, a3_loop0(i, length, sum, a), a)
: sum;
}
int a3(const int *a, int length) {
return a == 0 || length <= 0
? 0
: a3_loop1(0, length, 0, a);
}
答案 2 :(得分:0)
我会发布这个,因为我看到其他答案每个循环使用1个函数,这是不必要的。
你只能有一个递归函数:
int a3_impl(int* a, int length, int i, int j)
{
if (i >= length)
return 0;
if (j >= length)
return a3_impl(a, length, i + 1, i + 1);
return a[j] + a3_impl(a, length, i, j + 1);
}
int a3(int* a, int length)
{
if(a == 0 || length <= 0)
return 0;
return a3_impl(a, length, 0, 0);
}