【问题标题】:Find a series with recursion使用递归查找序列
【发布时间】:2017-05-27 20:27:22
【问题描述】:

我正在尝试编写一个 recursive 函数,它通过指针及其大小获取数组,并返回数组中最长的一系列相同相邻数字的长度(假设有系列),

例如:

array: {1 2 3 3 4 5 6 6 6 6 7 8} 
returns-->: 4 

但我不知道我的功能有什么问题;我想我完全错了。

关于如何解决它的任何想法?

#include <stdio.h>
#include <stdlib.h>

int LongestSeries(int* arr, int size, int* count, int* maxcount);


int main()
{
    int i, size, *arr, count=0, maxcount=0;

    // allocation an array (unknow size)
    {
        printf("Enter Size of the Array-->:");
        scanf("%d", &size);

        arr = (int*)malloc(size * sizeof(int));
        if (arr == NULL)
        {
            printf("Error!!");
            exit(1);
        }
        printf("Enter Numbers for the Array:\n");
        for (i = 0; i < size; i++)
        {
            printf("Enter a Number-->:");
            scanf("%d", &arr[i]);
        }
    }
    for (i = 0; i < size; i++)
        printf(" %d ", arr[i]);
    printf("\n");

    printf(" %d \n", LongestSeries(arr, size, count, maxcount));

    free(arr);
    return 0;
}


int LongestSeries(int* arr, int size, int* count, int* maxcount)
{
    if (arr[size-1] == arr[size-2])
        count++;
    if (maxcount<count)
        maxcount = count;

    LongestSeries(arr, size - 1, count, maxcount);

    if (*arr==arr[0])
        return maxcount;
}

【问题讨论】:

  • 我们不是来写你的代码的。请学习使用您的调试器
  • 那么,你想找到最长的重复数字序列,而不是最长的连续数字序列?在您的示例中,这两个都是 4。
  • 您正在比较 maxcount &lt; count 当两者都是指针时,您可能想要比较它们的值

标签: c arrays recursion


【解决方案1】:

您的代码存在一些问题:

1 - 函数 LongestSeries 需要一个指向 countmaxcount 参数的指针,但您传递了变量的值。您需要更改函数调用以发送地址引用,如下所示:printf(" %d \n", LongestSeries(arr, size, &amp;count, &amp;maxcount));

2 - 您的递归终止条件位于递归调用下方,导致递归永无止境。您需要将其放在递归调用之上,最好是递归函数中的第一条语句。

3 - 由于您的 countmaxcount 参数是指针,因此您必须使用解引用运算符来处理值而不是其地址:

从此:

if (arr[size-1] == arr[size-2])
        count++;
    if (maxcount<count)
        maxcount = count;

到这里:

if (arr[size-1] == arr[size-2])
        ++*count;
    if (*maxcount < *count)
        *maxcount = *count;

4 - 这同样适用于您的 return 语句:您正在返回指针,但您的函数期望返回一个 int,所以:

从此:

if (*arr==arr[0])
        return maxcount;

到这里:

if (*arr==arr[0])
        return *maxcount;

5 - 由于您需要最长的系列,您的 count 变量需要从 1 开始,而不是 0,因为数字序列中可能的最低系列是 1,而不是 0。

希望对你有帮助。

【讨论】:

  • 您是否尝试过您的解决方案?你确定*++count 是你想要的吗?以及将ints countmaxcount 传递到函数中的OP 代码怎么样,该函数需要指向int 的指针;以及为什么 OP 首先传递指针。 OP 代码有这么多问题......
  • *arr==arr[0]在什么情况下会为假?我能想到的唯一一个涉及 NaN,但在这种情况下,arrint 的数组。只是说'在大多数情况下,尝试像这样“修复”代码是不值得的:这不是 SO 的设计目的,它对 OP(需要学习如何学习)和未来都没有帮助读者。
  • @DavidBowling 对不起,我的错误。我更改了代码示例。我不太精通C,只是想提供帮助。是的,我测试了代码并按预期工作。
  • 一开始我没有注意到,但我现在看到你已经提到 OP 传递的是 ints 而不是指针。尽管如此,即使您进行了更正,发布的代码也不起作用。在我看来,更根本的问题是 OP 误解了递归。
  • @rici 是的,这个条件是错误的,如果他在每次递归调用时减去大小,它可能会检查大小作为终止条件。
【解决方案2】:

正如@MarcLaurent 所指出的,发布的代码存在很多问题。但从根本上说,这种方法似乎存在缺陷。编写递归函数的目的不是让事情变得困难,而是让事情变得简单。适合递归的问题可以分解为更小的子问题。

对于手头的问题,找到数组中最长的重复数字序列的长度,一种递归方法会承认这个长度要么是重复数字的初始序列的长度,要么是最长序列的长度数组其余部分中的重复数字。在代码中,这可能看起来像:

size_t longest_seq(size_t sz, int *a)
{
    if (sz == 0) {
        return 0;
    }
    size_t count = init_seq(sz, a);
    return MAX(count, longest_seq(sz - count, a + count));
}

这里,如果数组不包含元素(基本情况),则返回0。否则,返回初始序列的长度或数组剩余部分中最长的序列中的较大者。 MAX 在这里是一个宏,很容易定义,我们只需要编写一个函数来查找初始序列的长度。这也可以是递归的,尽管不是必须的。

找到初始序列长度的递归函数可能如下所示:

size_t init_seq(size_t sz, int *a)
{
    if (sz == 0) {
        return 0;
    }
    return 1 + ((sz > 1 && a[0] == a[1]) ? init_seq(sz - 1, a + 1) : 0);
}

这里,如果数组不包含元素(基本情况),那么长度显然是0,否则返回值是1加上数组剩余部分的初始序列的长度(如果有下一个元素,并且该元素与第一个元素相同),或0

通过这种方式分解问题,解决方案简单易懂。这是实现上述想法的完整程序:

#include <stdio.h>

#define MAX(X, Y) (X) > (Y) ? (X) : (Y)

size_t longest_seq(size_t, int *);
size_t init_seq(size_t, int *);

int main(void)
{
    size_t arr_sz;
    printf("Enter number of elements: ");
    scanf("%zu", &arr_sz);

    int arr[arr_sz];

    printf("Enter array values:\n");
    for (size_t i = 0; i < arr_sz; i++) {
        scanf("%d", &arr[i]);
    }

    printf("Longest sequence of repeats: %zu\n", longest_seq(arr_sz, arr));

    return 0;
}

size_t longest_seq(size_t sz, int *a)
{
    if (sz == 0) {
        return 0;
    }
    size_t count = init_seq(sz, a);
    return MAX(count, longest_seq(sz - count, a + count));
}

size_t init_seq(size_t sz, int *a)
{
    if (sz == 0) {
        return 0;
    }
    return 1 + ((sz > 1 && a[0] == a[1]) ? init_seq(sz - 1, a + 1) : 0);
}

示例程序交互:

Enter number of elements: 12
Enter array values:
1 2 3 3 4 5 6 6 6 6 7 8
Longest sequence of repeats: 4

【讨论】:

    【解决方案3】:
    int LongestSeries(int* arr, int size, int count, int maxcount){
        if(size == 0)
            return maxcount < count ? count : maxcount;
    
        if(count == 0){
            return LongestSeries(arr + 1, size - 1, 1, maxcount);
        } else {
            if(arr[-1] == *arr){
                return LongestSeries(arr + 1, size - 1, count + 1, maxcount);
            } else {
                if(count > maxcount)
                    maxcount = count;
                return LongestSeries(arr + 1, size - 1, 1, maxcount);
            }
        }
    }
    
    int main(void){
        int arr[] = {1, 2, 3, 3, 4, 5, 6, 6, 6, 6, 7, 8};
        int size = sizeof(arr)/sizeof(*arr);
        printf("%d\n", LongestSeries(arr, size, 0, 0));
    }
    

    减少代码:

    int LongestSeries(int* arr, int size, int count, int maxcount){
        if(size == 0)
            return maxcount < count ? count : maxcount;
    
        if(count == 0 || arr[-1] != *arr){
            if(count > maxcount)
                maxcount = count;
            return LongestSeries(arr + 1, size - 1, 1, maxcount);
        }
        return LongestSeries(arr + 1, size - 1, count + 1, maxcount);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多