算法设计艺术——编程珠玑第八章

来源:互联网 发布:华讯网络在哪 编辑:程序博客网 时间:2024/05/17 20:30
算法设计艺术——编程珠玑第八章

 下面是书本中讲解的四个算法:

       问题:求一维数组中连续子向量的最大和。

       例如:a[6]={3,4,-2,-9,10,8}; 则最大连续子向量的和 为 10+8 = 18

       1)解法一:简单算法

[html] view plaincopy
  1. #include <stdio.h>  
  2. #define max(a, b) ((a)>(b)?(a):(b))  
  3. int main()  
  4. {  
  5.     int a[6]={3,4,-2,-9,10,8};   
  6.     int i,j,k;  
  7.     int sum=0;  
  8.     int maxsofar=0;  
  9.   
  10.       
  11.     for(i=0;i<6;++i)  
  12.     {  
  13.         for(j=i;j<6;++j)  
  14.         {  
  15.             sum=0;  
  16.             for(k=i;k<=j;++k)  
  17.             {  
  18.                 sum+=a[k];  
  19.             }  
  20.             maxsofar=max(maxsofar,sum);  
  21.         }  
  22.     }  
  23.       
  24.     printf("max=%d\n",maxsofar);  
  25.     return 0;  
  26. }  
       2)两个平方算法

             算法一:

[html] view plaincopy
  1. #include <stdio.h>  
  2. #define max(a, b) ((a)>(b)?(a):(b))  
  3. int main()  
  4. {  
  5.     int a[6]={3,4,-2,-9,10,8};   
  6.     int i,j;  
  7.     int sum=0;  
  8.     int maxsofar=0;  
  9.   
  10.       
  11.     for(i=0;i<6;++i)  
  12.     {  
  13.         sum=0;  
  14.         for(j=i;j<6;++j)  
  15.         {  
  16.                       
  17.             sum+=a[j];  
  18.             maxsofar=max(maxsofar,sum);  
  19.         }  
  20.     }  
  21.       
  22.     printf("max=%d\n",maxsofar);  
  23.     return 0;  
  24. }  

              算法二:
[html] view plaincopy
  1. #include <stdio.h>  
  2. #define max(a, b) ((a)>(b)?(a):(b))  
  3. int main()  
  4. {  
  5.     int a[6]={3,4,-2,-9,10,8};  
  6.     int cumarr[6]; cumarr[-1]=0;  
  7.     int i,j;  
  8.     int sum=0;  
  9.     int maxsofar=0;  
  10.   
  11.     for(i=0;i<6;++i)  
  12.     {  
  13.         cumarr[i] = cumarr[i-1] + a[i];  
  14.     }  
  15.     for(i=0;i<6;++i)  
  16.     {  
  17.         sum=0;  
  18.         for(j=i;j<6;++j)  
  19.         {  
  20.                       
  21.             sum = cumarr[j] - cumarr [i-1];  
  22.             maxsofar=max(maxsofar,sum);  
  23.         }  
  24.     }  
  25.       
  26.     printf("max=%d\n",maxsofar);  
  27.     return 0;  
  28. }  


            3)分治算法

思想:以m为分界线,最大值有三种情况

            一:在m左侧

            二:在m右侧

            三:跨越m

关键:最初求解左右最大值时候,一定要从中间向两侧递增。看源码解释……

[html] view plaincopy
  1. #include "stdio.h"  
  2. #define max(a,b)  a>b?a:b  
  3.   
  4. int a[6]={3,4,-2,-9,10,8};  
  5. int max2(int a,int b,int c)  
  6. {  
  7.     if(a>b&&a>c)  
  8.         return a;  
  9.     else if(b>a&&b>c)  
  10.         return b;  
  11.     else return c;    
  12. }    
  13. int maxsum(int l,int u)  
  14. {  
  15.     int i,m,sum,lmax,rmax;  
  16.     if(l>u)  
  17.         return 0;  
  18.     if(l==u)  
  19.         return max(0,a[l]);  
  20.         m=(l+u)/2;  
  21.       
  22.     lmax = sum =0;  
  23.     for(i=m;i>=l;--i)  
  24.     {  
  25.         sum += a[i];  
  26.         lmax =max(lmax,sum);  
  27.     }  
  28.       
  29.     printf("m=:%d\n",m);  
  30.     rmax =sum =0;  
  31.     for(i=m+1;i<=u;++i)  
  32.     {  
  33.         sum += a[i];  
  34.         rmax =max(rmax,sum);  
  35.     }  
  36.     return max2(lmax + rmax , maxsum(l,m) , maxsum(m+1,u) );  
  37. }  
  38. int main()  
  39. {     
  40.     int maxsofar=maxsum(0,5);  
  41.     printf("max=%d",maxsofar);  
  42.     return 0;  
  43. }  


【注意】 max2() 如果用宏  #define  max(a,b,c)    max(a,b) >c?max(a,b):c  则不会得到正确结果

 

           4)扫描算法

[html] view plaincopy
  1. #include "stdio.h"  
  2. int main()  
  3. {     
  4.     int a[6]={3,4,-2,-9,10,8};  
  5.     int i,sum=0;  
  6.     for(i=0;i<6;++i)  
  7.     {  
  8.         sum+=a[i];  
  9.         if(sum<0)  
  10.             sum=0;  
  11.     }  
  12.       
  13.     printf("max=%d",sum);  
  14.     return 0;  
  15. }  
参考来源:http://blog.csdn.net/tianshuai11/article/details/7566244
原创粉丝点击