【问题标题】:What is wrong with this C++ recursion function of mine?我的这个 C++ 递归函数有什么问题?
【发布时间】:2015-11-20 13:34:18
【问题描述】:

首先抱歉,如果代码奇怪。按照此处的分享说明进行操作后看起来不错,但这是我的第一次。无论如何,我有一个类分配,我需要在其中创建一个递归函数,当给定一个数组时,它会返回其元素的总和。我找到了可以在线使用的解决方案,但它们似乎与我的足够相似。我的代码运行,但总和是一个巨大的整数,特别是总和输出下方的代码是 -858993459。我以前见过一些类似的事情,我尝试过可能是一个常见的错误,但我至少没有找到任何东西。请帮助解释发生了什么,我想使用我设置的参数(我已经看到了其他方式)因为我希望我的代码至少有点独特。提前谢谢大家!

    #include <iostream>
    #include <array>
    #include <string>
    using namespace std;

    int getSumOfElements(int intArray[], int firstElement, int lastElement, int sum) {
    if (firstElement > lastElement)
        return sum;
    else {
        sum += intArray[firstElement] + intArray[lastElement];
        getSumOfElements(intArray, firstElement + 1, lastElement - 1, sum);
        }
    }

    int main()
    {
        int sum = 0, lastElement, firstElement = 0;
        int exampleArray1[] = { 1, 5, 6, 12, 7 }, exampleArray2[] = { 3, -5, -16, 4, 10, 1, 7 };

        lastElement = sizeof(exampleArray1) / sizeof(exampleArray1[0]);
        sum = getSumOfElements(exampleArray1, firstElement, lastElement, sum);
        cout << "The sum of all elements in Array1 are " << sum << endl;

        lastElement = sizeof(exampleArray2) / sizeof(exampleArray2[0]);
        sum = getSumOfElements(exampleArray2, firstElement, lastElement, sum);
        cout << "The sum of all elements in Array2 are " << sum << endl;

        system("pause");
   }

【问题讨论】:

  • 您没有将 getSumOfElements 的递归调用分配给任何东西。同样如所写,它没有右大括号,所以当你在这里复制它时一定发生了一些事情。
  • 这可能是众多问题中的一个,但如果只添加数组的firstElement和lastElement,你是如何对数组元素求和的?
  • 另外,对于奇数个数组元素,您最终会计算中间项两次。您应该添加一个检查,如果 first == last,则只添加该元素一次。
  • 最初 lastElement 将在您的数组之外(因为最后一个有效的数组元素位于 (# of elements in array - 1)。
  • 右括号是一个错字,我修复了它,但它在我的原始程序中。感谢您指出奇怪的元素。我使用的旧代码只是简单地交换了元素,那时这不是问题。非常感谢您指出我的变量 lastElement 只需减去一个。信不信由你,我从旧代码中得到了它,但是当我显然没有想到时将其删除 xD 再次感谢大家!

标签: c++ recursion


【解决方案1】:

您在数组之外进行索引。

int lastElement = sizeof(exampleArray1) / sizeof(exampleArray1[0]);
sum = getSumOfElements(exampleArray1, firstElement, lastElement, sum);

然后你做

sum += intArray[firstElement] + intArray[lastElement];

在第一次调用期间,lastElement 将在数组之外进行索引。 你应该这样做

sum = getSumOfElements(exampleArray1, firstElement, lastElement - 1, sum);

这就是为什么你会得到一个“奇怪”的整数值,比如 -858993459。

【讨论】:

  • 同样if(firstElement &gt; lastElement) 应该是if(firstElement &gt;= lastElement)
  • 一般问题是lastElement其实是元素个数,最后一个元素的索引是lastElement - 1
  • 我最终这样做了,但它似乎仍然无法正常工作。即使在进行了所有其他更改之后。现在我让它检查 first > second then else if first == second else 什么我以前。我编辑了上面的问题以反映更改。
  • @JoshuaRG1993 仔细考虑大量重写问题。它使所有现有的答案看起来很愚蠢。一般来说,提出一个新问题比移动旧问题的目标柱更好。一方面,如果我不知道它的写作背景,很难判断这是否是一个好的答案。
  • 好的,为了清楚起见,您建议不要编辑主要问题,对吗?
【解决方案2】:

在 getSumOfElements 的其他条件下,您没有返回任何东西,它是用于返回的垃圾值。

【讨论】:

  • 我不确定是否需要。在调用我的函数之前,我尝试了使用和不使用“返回”,结果仍然相同。
  • 您的代码中还有其他问题。但是您的函数返回垃圾的主要原因是缺少返回语句。有了它你会得到不正确的结果,但不会是垃圾。
  • @JoshuaRG1993 绝对需要返回语句!尝试使用-Wall -Werror 进行编译,您的代码将无法编译,因为并非所有路径都返回int
  • 好的,谢谢。我会把它放在那里。我一定没有想清楚,因为我找不到处理奇数或偶数数组的简单方法。所以也许我会在里面放一个 if 语句,所以有两个代码块,一个是奇数,另一个是偶数。
  • 刚刚意识到我的 else if first == last case 只是首先添加而不是 intArray[first]。所以代码现在不适用于奇数数组......
【解决方案3】:

感谢以上所有帮助 ^^ 所有 cmets 都给出了答案,但不幸的是我只能选择一个。但是,我重新编辑了最初的问题,使其与第一次被问到时一样,下面我将根据所有输入显示工作代码。

    int getSumOfElements(int intArray[], int firstElement, int lastElement, int sum) {
        if (firstElement > lastElement)
            return sum;
        else if (firstElement == lastElement) {
            sum += intArray[firstElement];
            return sum;
        }
        else {
            sum += intArray[firstElement] + intArray[lastElement];
            return getSumOfElements(intArray, firstElement + 1, lastElement - 1, sum);
        }
    }

    int main()
    {
        int sum1, sum2, sum3, lastElement, firstElement = 0;
        int exampleArray1[] = { 1, 5, 6, 12, 7 }, exampleArray2[] = { 3, -5, -16, 4, 10, 1, 7 },
            exampleArray3[] = { 1, 3, 5, 6 };

        lastElement = sizeof(exampleArray1) / sizeof(exampleArray1[0]) - 1;
        sum1 = getSumOfElements(exampleArray1, firstElement, lastElement, 0);
        cout << "The sum of all elements in Array1 are " << sum1 << endl;

        lastElement = sizeof(exampleArray2) / sizeof(exampleArray2[0]) - 1;
        sum2 = getSumOfElements(exampleArray2, firstElement, lastElement, 0);
        cout << "The sum of all elements in Array2 are " << sum2 << endl;

        lastElement = sizeof(exampleArray3) / sizeof(exampleArray3[0]) - 1;
        sum3 = getSumOfElements(exampleArray3, firstElement, lastElement, 0);
        cout << "The sum of all elements in Array3 are " << sum3 << endl;

        system("pause");
    }

【讨论】:

    【解决方案4】:

    我知道,自您最初提出问题以来,您已对问题进行了修改,但请暂时保留您的问题。

    你的递归函数有几个问题(原文如下):

    int getSumOfElements(int intArray[], int firstElement, int lastElement, int sum) {
    if (firstElement > lastElement)
        return sum;
    else if (firstElement == lastElement)
        sum += firstElement;
    else {
        sum += intArray[firstElement] + intArray[lastElement];
        getSumOfElements(intArray, firstElement + 1, lastElement - 1, sum);
        }
    }
    

    在最简单的形式中,递归主要有两个方面:基本情况递归情况。您有 2 个基本案例(这很好):

    1. 当您当前处于 firstElement 索引大于 lastElement 索引的情况时(使用偶数大小的数组完成)
    2. 当您的 firstElement 索引与您的最后一个元素索引相同时(使用奇数大小的数组完成)

    您应该执行实际逻辑的唯一时间是在 递归 的情况下。因此,您的基本情况应该简单地返回0(第一个)或intArray[firstElement](第二个值)。为什么?因为您的函数仅返回从 firstElement 到 lastElement 的整数之和。如果你已经越过了,那么你已经添加了所有的数字。如果该索引相同,那么总和就是值本身,因为这是您仍然需要添加的唯一值。

    您只能在递归情况下进行加法。您要说的是getSumOfElements(..., first, last, sum)intArray[first] + intArray[last] + getSumOfElements(..., first+1, last-1, sum) 相同(添加两端并通过再次执行递归添加其余部分,总是更接近中间)。因此,您的递归案例应该简单地将数组的 firstElement 索引、数组的 lastElement 索引以及 rest 值的总和相加,然后返回。

    固定版本看起来像:

    int getSumOfElements(int intArray[], int firstElement, int lastElement) {
        if (firstElement > lastElement) {
            return 0;
        }
        if (firstElement == lastElement) {
            return intArray[firstElement];
        }
        else {
            return intArray[firstElement] + intArray[lastElement] + getSumOfElements(intArray, firstElement + 1, lastElement - 1);
        }
    }
    

    请注意,您不需要在递归调用中携带总和,因为您在每次调用中返回总和到目前为止。我真的希望对递归有更多的了解。

    工作样本:http://ideone.com/9xkMqT

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-04-27
      • 1970-01-01
      • 1970-01-01
      • 2023-03-23
      • 2012-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多