所有连续子阵列的最大总和

时间:2016-01-31 16:48:32

标签: c arrays contiguous

我有一个练习要解决:“编写一个有效的C程序,在一维整数数组中找到最大的连续子阵列。数组的连续子阵列被定义为任何元素的序列在数组中有效的连续索引集。

让我们举一个数组{5,-3,4}的例子。可能的连续子阵列组合是{5},{ - 3},{4},{5,-3},{ - 3,4}和{5,-3,4}。注意{5,4}不是有效的子阵列,因为5和4的索引不连续。 连续的子阵列{5,-3,4}具有最大的总和6.“

我试图解决它,但我意识到我甚至不理解这个问题,因为如果我有一个包含5个不同值的数组,结果应该是10,而我会说15( 5 不同的元素+ 1 作为一个整体+ 4 元素,如果采用2 + 2 < 3 ,如果采取3 + 3 + 2 如果四乘4)。

在尝试编码之前(在C中),我想知道是否有人可以帮助我理解问题本身。

1 个答案:

答案 0 :(得分:0)

这就是我解决问题的方法。这不一定是最佳解决方案,但我相信它应该有效。

考虑数组:{1,-2,3,5,-4}并考虑如何手动编写所有子数组:

  1. 从5元素数组开始:{1,-2,3,5,-4}总和:3
  2. 接下来写出4元素阵列:
       {1,-2,3,5}总和:7
       {-2,3,5,-4}总和:2
  3. 继续使用3元素阵列:
       {1,-2,3}总和:2
       {-2,3,5}总和:6
       {3,5,-4}总和:4
  4. 现在是2元素阵列:
       {1,-2}总和:-1
       {-2,3}总和:1
       {3,5}总和:8
       {5,-4}总和:1
  5. 最后,1元素阵列:
       {1}总和:1
       {-2}总和:-2
       {3}总和:3
       {5}总和:5
       {-4}总和:-4
  6. 看起来最大的金额是8。

    你应该在这里看到一个模式,我从数组的长度开始,5在这里 case,并将它减少一直到我处理单元素数组。我也从数组的第0个元素开始,并尝试根据长度创建一个有效的数组。例如,如果我使用四个元素数组,从数组元素0开始,它可以通过array [0] - &gt;创建一个子数组。 array [3]和array [1] - &gt; array [4](这是数组切片,像Python这样的一些语言有明确的表示法来执行数组切片,而C则没有)。生成每个切片后,对元素求和,完成后查找最大值

    现在,我的代码就像这样

    int main(void)
    {
        int array[] = {1, -2, 3, 5, -4};
        int max = -1;                         // will hold largest sum
        int len = sizeof(array)/sizeof(int);  // C-idiom to find length of array
    
        for(int slen = len; slen > 0; slen--)           // loop for length of sub-arrays
        {
            for(int jdx = 0; jdx+slen <= len; jdx++)   // looping over elements in original array
            {
                 int temp = calcSum(array, jdx, slen);
                 if(temp > max)
                     max = temp;
    
            }
        }
        printf("maximum sum of sub-array is: %d\n", max);
    }
    

    现在剩下的就是编写calcSum函数了。它需要三个参数 - 第一个是原始数组,第二个是子数组的开始位置,这是子数组的长度。

    int calcSum(int* array, int start, int len)
    {
        int    sum = 0;
        printf("[%d:%d]: {", start, start+len);
        for(int ndx = 0; ndx < len; ndx++)
        {
            printf("%d,", array[start+ndx]);
            sum = sum + array[start+ndx];
        }
    
        printf("} the sum is %d\n", sum);
        return sum;
    }
    

    我在那里撒了几张printf,所以你可以看到程序循环时发生了什么。我的切片表示法是[start:length]所以[1:3]将是从索引1开始并且长度为3的数组( ie array [1],array [2] ,array [3])。

    将上述内容编译为gcc -std=c99 -pedantic -Wall test.c -o temp并执行此操作,产生:

    D:\Users\******\GNUHome>temp.exe
    [0:5]: {1,-2,3,5,-4,} the sum is 3
    [0:4]: {1,-2,3,5,} the sum is 7
    [1:4]: {-2,3,5,-4,} the sum is 2
    [0:3]: {1,-2,3,} the sum is 2
    [1:3]: {-2,3,5,} the sum is 6
    [2:3]: {3,5,-4,} the sum is 4
    [0:2]: {1,-2,} the sum is -1
    [1:2]: {-2,3,} the sum is 1
    [2:2]: {3,5,} the sum is 8
    [3:2]: {5,-4,} the sum is 1
    [0:1]: {1,} the sum is 1
    [1:1]: {-2,} the sum is -2
    [2:1]: {3,} the sum is 3
    [3:1]: {5,} the sum is 5
    [4:1]: {-4,} the sum is -4
    maximum sum of sub-array is: 8
    

    N.B。我在Windows 7 Professional上用gcc版本4.8.3(来自mingw)编译了这个。