zoukankan      html  css  js  c++  java
  • C Algorithm.Max_length

    Mark Allen Weiss的data structures and algorithm analysis in c

    求一个整数序列的最大的连续子列和:

     1 #include <stdio.h>
     2 
     3 static int Max3( int A, int B, int C )
     4 {
     5     return A > B ? ( A > C ? A : C ) : ( B > C ? B : C );
     6 }
     7 
     8 static int maxsubsum(const int a[], int left, int right)
     9 {
    10         int maxleftsum, maxrightsum;
    11         int maxleftbordersum, maxrightbordersum;
    12         int leftbordersum, rightbordersum;
    13         int center, i;
    14         
    15         if(left == right)
    16                 if(a[left] > 0)
    17                         return a[left];
    18                 else
    19                         return 0;
    20 
    21         center = ( left + right ) / 2;
    22         maxleftsum = maxsubsum(a, left, center);
    23         maxrightsum = maxsubsum(a, center + 1, right);
    24 
    25         maxleftbordersum = 0; leftbordersum = 0;
    26 
    27         for( i = center; i >= left; i--)
    28         {
    29                 leftbordersum += a[i];
    30                 if(leftbordersum > maxleftbordersum)
    31                         maxleftbordersum = leftbordersum;
    32         }
    33 
    34         maxrightbordersum = 0; rightbordersum = 0;
    35         for(i= center + 1; i<= right; i++)
    36         {
    37                 rightbordersum += a[i];
    38                 if( rightbordersum > maxrightbordersum)
    39                         maxrightbordersum = rightbordersum;
    40         }
    41 
    42         return Max3(maxleftsum, maxrightsum, maxleftbordersum + maxrightbordersum);
    43 }
    44 
    45 maxsubsesquencesum( const int a[], int n)
    46 {
    47         return maxsubsum( a, 0, n-1);
    48 }
    49 
    50 int main()
    51 {
    52      static int A[ ] = { 4, -3, 5, -2, -1, 2, 6, -2 };
    53      static int B[ ] = { -3, -2 };
    54         printf( "Maxsum = %d
    ", maxsubsesquencesum( B, sizeof( B ) / sizeof( B[ 0 ] ) ) );
    55     return 0;
    56 }

    上面的代码的解释:

    把一个序列从中间分成两个子序列,然后对这两个子序列分别求最大子列的和 S1和S2,还有,求出包含中间分界元素的最大子列的和S3, 三者中的最大者就是要求的这整个序列的最大子列的和,Max3(S1, S2,S3)。

    这个方法用到了递归方法,即,当所求序列的元素很多时,把他分解成两个更小的子列,当子列分解到只剩下1个元素时,就可以向上返回最大子列的和。

    Weiss对基础情况的处理中,有点粗糙了,即上述代码第15~19行中,

    15         if(left == right)
    16                 if(a[left] > 0)
    17                         return a[left];
    18                 else
    19                         return 0;
    为什么当 a[left] <= 0 的时候就要返回0呢,如果整个序列都是负数呢? 那就应该返回此序列中的最大负数就可以了,因为 负数+负数 会越加越小。

    Weiss又给出了一个更简洁的算法:
     1 int maxsubsum(int a[], int n)
     2 {
     3     int thisSum=maxSum=0,j;
     4 
     5     for(j=0; j < n; j++)
     6     {
     7         if(thisSum > maxSum)
     8             maxSum=thisSum;
     9         else if(thisSum < 0)
    10             thisSum = 0;
    11     }
    12 
    13     return maxSum;
    14 }

    这个算法的思路是,顺次扫描序列的元素并求其和,如果当前和大于先前保存的最大和,则置最大和为当前和。

    如果当前和小于0,则置当前和为0。

    这个算法同样假设最大和为负数时,返回0。

    根据 http://blog.csdn.net/v_JULY_v/article/details/6444021 第一节第3个算法,加上我的一个改进,可以给出序列元素全是负数的情况下的解:

     1 static int maxsubsum(int a[], int n)
     2 {
     3     int thisSum, maxSum, maxelem, j;
     4     thisSum=0;
     5     maxSum=maxelem=a[0];
     6     for(j=0; j < n; j++)
     7     {
     8         if(thisSum>=0)     //如果加上某个元素,sum>=0的话,就加  
     9             thisSum+=a[j];  
    10         else     
    11             thisSum=a[j];  //如果加上某个元素,sum<0了,就不加  
    12         
    13         if( maxelem < a[j])
    14             maxelem = a[j];
    15             
    16         if(thisSum > maxSum)
    17             maxSum=thisSum;
    18             
    19         if(maxelem > maxSum)
    20             maxSum=maxelem;
    21     }
    22 
    23     return maxSum;
    24 }
    25 
    26 int main()
    27 {
    28     static int a[] = { 4, -3, 5, -2, -1, 2, 6, -2 };
    29     static int b[] = { -4, -3, -5, -2, -1, -2, -6, -2 };
    30     static int c[] = { 4, -3, 5, -2, 0, -1, 2, 16, -2 };
    31     
    32     printf( "Maxsum of a = %d
    ", maxsubsum( a, sizeof( a ) / sizeof( a[ 0 ] ) ) );
    33     printf( "Maxsum of b = %d
    ", maxsubsum( b, sizeof( b ) / sizeof( b[ 0 ] ) ) );
    34     printf( "Maxsum of c = %d
    ", maxsubsum( c, sizeof( c ) / sizeof( c[ 0 ] ) ) );
    35     return 0;
    36 }
  • 相关阅读:
    discuz制作
    Cookie和Session专题
    ecmall二次开发 直接实例化mysql对象
    ecmall widgets 挂件开发详解
    都是iconv惹的祸
    discuz+ecmall+phpcms整合
    replace into
    权限管理设计二
    权限管理设计一
    SVN服务器搭建和使用(二)
  • 原文地址:https://www.cnblogs.com/freudshow/p/3463706.html
Copyright © 2011-2022 走看看