Debug递归问题;输出不正确

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Debug递归问题;输出不正确相关的知识,希望对你有一定的参考价值。

我正在尝试根据给出的说明编写程序:

找到一个序列中最长(相邻)递增子序列的长度向量与n个元素。例如,考虑以下向量包含12个元素:

5、8、10、5、2、1、12、12、83、30、40、65

形成递增序列(元素的子序列)的元素整个数组)是:

5、8、10(元素数为3)5(1)2(1)1,12,12,83(4)30,40,65(3)

因此,最长的递增子序列的长度为4。请注意,相等的值计为递增的值。

我的代码必须以递归的方式编写,以便进行理解主题的练习。当尝试更早地编译程序而不是4时,我的输出为12。我需要帮助以获取正确的输出。我怀疑我的计数器没有正确增加。我的“最大元素”功能正常运行,但是问题出在我的序列功能之内。帮助将不胜感激。我仍在学习递归的工作方式。

这是我的代码(.hpp文件只有两个原型):

#include <iostream>
#include <vector>
#include "increasing_sequences_recursive.hpp"

int main() {
    std::vector<int> numbers;
    int input;
    int startIdx = 0;

    std::cout << "Enter a set of numbers (0 to stop): " << std::endl;

    while (true) {
        std::cin >> input;

        if (input != 0) {
            numbers.push_back(input);
        }
        else {
            break;
        }
    } 

    startIdx = numbers.size();
    std::cout << "Length of longest sequence: " <<
           increasing_sequences_recursive(numbers, startIdx);

    return 0;
}

// Recursively find the largest sequence
int increasing_sequences_recursive(std::vector<int> &numbers, int startIdx) {
    int counter = 0;
    int maxCounter = 0;

    if (startIdx == 1) {
        return 1;
    }
    int largeElmt = largestElement(numbers, startIdx);
    counter += increasing_sequences_recursive(numbers, startIdx - 1);
    if (numbers[startIdx - 1] <= largeElmt) {//numbers[startIdx]) {
        counter++;
        if (counter >= maxCounter) {
            maxCounter = counter;
        }
    }
    else {
        if (counter >= maxCounter) {
            maxCounter = counter;
        }
    }

    return maxCounter;
}

// Recursively find the largest element.
int largestElement(std::vector<int> &numbers, int n) {
    // Assume n >= 1; Find largest element in the first
    // n elements of n "numbers"
    if (n == 1)
        return numbers[n - 1];

    int res = largestElement(numbers, n - 1);
    if (res > numbers[n - 1])
        return res;

    return numbers[n - 1];
}
答案

这听起来像homework assignment,因此我不会在您的代码中发现错误,因为它在任何意义上都不会对您有用。相反,我会给出一些提示,希望可以引导您朝正确的方向发展。

首先,在您的代码中没有任何怪异的C ++。因此,它本质上不是一个C ++问题,而是一个算法问题。

递归的本质是根据参数较低值的任务,例如参数,制定参数化任务F(N)。用F(N-1)来定义一个简单的情况,例如F(0)。在您的情况下,F(N)可能代表“最长的递增子序列的长度,加上整个序列的前N + 1个元素”(我在这里使用“ N + 1”来支持从零开始的索引)。我们如何用F(N)来表示F(N-1)

让我们调用序列A,它是第N个元素A[N](从零开始)。那么我们可以说在F(N)情况下F(N-1)+1A[N] >= A[N-1],否则为1。检查自己。当然F(0)1。现在您的任务是将该定义转换为C ++。该代码应该比您想出的代码简单得多。但是再次,我不会在这里提供它,因为您应该自己制作。

HTH

另一答案

第一个算法缺陷:

这里有算法缺陷:

int largeElmt = largestElement(numbers, startIdx);    // (1)<========= 
counter += increasing_sequences_recursive(numbers, startIdx - 1);
if (numbers[startIdx - 1] <= largeElmt) {             // (2)<=========  
    counter++;

在(1)中,您需要在startIdx的第一个数字中查找最大的元素。由于largestElmt在子数组中最大,因此(2)中的条件始终为true。因此,您总是将递归结果从1开始加1。因此,最后,您只计算数组中的元素数(尽管很复杂)。

第二个算法缺陷:

现在,您可以通过检查最后一个数字是否在减少来纠正此问题:

 if (numbers[startIdx-2]<=numbers[startIdx - 1] )    // no need for largest

从索引的角度来看这是可以的,因为可以保证startIdx至少为2。不幸的是,您的递归没有考虑连续性。因此,您只需计算随后增加的对,而不会在中断的情况下重新启动计数。所以在这里您会找到8。

出路?

您需要在递归中区分延长序列的情况(仅将当前长度加一个)和中断(必须从1重新开始)。在这两种情况下,您都必须跟踪迄今为止的最长序列。因此,如果您希望逐元素递归,则至少需要传递更多作为递归参数。

但是一定要这样吗?如果不是,则可以循环查找数量递增的序列,并在找到中断后使用递归在数组的其余部分中找到最大的序列。这样会容易得多!

以上是关于Debug递归问题;输出不正确的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot:thymeleaf 没有正确渲染片段

使用递归的最小数组值不正确

标签菜单android - 不正确的调用片段

实验三:分别用forwhile和do-while循环语句以及递归方法计算n!,并输出算式

ajax异步提交 有时会出现无bug的数据处理异常-----debug没有问题,正常运行却数据处理不正确,极少机会会出现正常的处理结果

河内塔 C++(使用递归)