C ++ 2嵌套for循环转换为递归

时间:2018-06-16 14:34:04

标签: c recursion

您好我想将此代码转换为递归函数:

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()第二个循环和身体,但我在这里混合了一些东西。

我希望得到任何帮助:)

3 个答案:

答案 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;
}

让我们从最里面的循环开始。它使用周围范围内的jilengthsuma

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);
}