当前位置:软件学习 > 其它软件 >>

【编程珠玑】第八章:算法设计技术

一,概述
       问题:求一维数组中连续子向量的最大和。
       例如:a[6]={3,4,-2,-9,10,8}; 则最大连续子向量的和 为 10+8 = 18
       1)解法一:简单算法
[html] #include <stdio.h> 
#define max(a, b) ((a)>(b)?(a):(b)) 
int main() 

    int a[6]={3,4,-2,-9,10,8};  
    int i,j,k; 
    int sum=0; 
    int maxsofar=0; 
 
     
    for(i=0;i<6;++i) 
    { 
        for(j=i;j<6;++j) 
        { 
            sum=0; 
            for(k=i;k<=j;++k) 
            { 
                sum+=a[k]; 
            } 
            maxsofar=max(maxsofar,sum); 
        } 
    } 
     
    printf("max=%d\n",maxsofar); 
    return 0; 

       2)两个平方算法
             算法一:
[html]
#include <stdio.h> 
#define max(a, b) ((a)>(b)?(a):(b)) 
int main() 

    int a[6]={3,4,-2,-9,10,8};  
    int i,j; 
    int sum=0; 
    int maxsofar=0; 
 
     
    for(i=0;i<6;++i) 
    { 
        sum=0; 
        for(j=i;j<6;++j) 
        { 
                     
            sum+=a[j]; 
            maxsofar=max(maxsofar,sum); 
        } 
    } 
     
    printf("max=%d\n",maxsofar); 
    return 0; 

              算法二:
[html]
#include <stdio.h> 
#define max(a, b) ((a)>(b)?(a):(b)) 
int main() 

    int a[6]={3,4,-2,-9,10,8}; 
    int cumarr[6]; cumarr[-1]=0; 
    int i,j; 
    int sum=0; 
    int maxsofar=0; 
 
    for(i=0;i<6;++i) 
    { 
        cumarr[i] = cumarr[i-1] + a[i]; 
    } 
    for(i=0;i<6;++i) 
    { 
        sum=0; 
        for(j=i;j<6;++j) 
        { 
                     
            sum = cumarr[j] - cumarr [i-1]; 
            maxsofar=max(maxsofar,sum); 
        } 
    } 
     
    printf("max=%d\n",maxsofar); 
    return 0; 

            3)分治算法
思想:以m为分界线,最大值有三种情况
            一:在m左侧
            二:在m右侧
            三:跨越m
关键:最初求解左右最大值时候,一定要从中间向两侧递增。看源码解释……
[html]
#include "stdio.h" 
#define max(a,b)  a>b?a:b 
 
int a[6]={3,4,-2,-9,10,8}; 
int max2(int a,int b,int c) 

    if(a>b&&a>c) 
        return a; 
    else if(b>a&&b>c) 
        return b; 
    else return c;   
}   
int maxsum(int l,int u) 

    int i,m,sum,lmax,rmax; 
    if(l>u) 
        return 0; 
    if(l==u) 
        return max(0,a[l]); 
        m=(l+u)/2; 
     
    lmax = sum =0; 
    for(i=m;i>=l;--i) 
    { 
        sum += a[i]; 
        lmax =max(lmax,sum); 
    } 
     
    printf("m=:%d\n",m); 
    rmax =sum =0; 
    for(i=m+1;i<=u;++i) 
    { 
        sum += a[i]; 
        rmax =max(rmax,sum); 
    } 
    return max2(lmax + rmax , maxsum(l,m) , maxsum(m+1,u) ); 

int main() 
{    
    int maxsofar=maxsum(0,5); 
    printf("max=%d",maxsofar); 
    return 0; 

【注意】 max2() 如果用宏  #define  max(a,b,c)    max(a,b) >c?max(a,b):c  则不会得到正确结果
 
           4)扫描算法 www.zzzyk.com
[html]
#include "stdio.h" 
int main() 
{    
    int a[6]={3,4,-2,-9,10,8}; 
    int i,sum=0; 
    for(i=0;i<6;++i) 
    { 
        sum+=a[i]; 
        if(sum<0) 
            sum=0; 
    } 
     
    printf("ma

补充:软件开发 , 其他 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,