zoukankan      html  css  js  c++  java
  • 计算最大子段(分治法)

    这个程序使用分治法计算最大子段,结果为最大子段之和,用递归程序实现。

    原始数据使用随机函数生成。

    采用结构化程序设计,可以很容易改为从标准输入或文件读入数据,只需要修改函数getData即可。

    数据个数由宏定义给出,也可以轻松地改为输入

    /*
     * 最大子段算法程序
     */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define N 13
    
    void getData(int [], int);
    
    int maxsumfun(int a[], int left, int right);
    
    int main(void)
    {
        int a[N], i;
    
        getData(a, N); /* 获得数据放入数组a中 */
    
        printf("datas: ");
        for (i = 0; i < N; i++)
            printf("%d ", a[i]);
        printf("
    ");
    
        int ms;
        ms = maxsumfun(a, 0, N - 1);
    
        printf("maxsum=%d
    ", ms);
    
        return 0;
    }
    
    int maxsumfun(int a[], int left, int right)
    {
        int maxsum = 0;
    
        if(left == right)
        {
            if(a[left] > 0)
                maxsum = a[left];
            else
                maxsum = 0;
        }
        else
        {
            int mid, leftsum, rightsum, midsum;
    
            mid = (left + right) / 2;
            leftsum = maxsumfun(a, left, mid);
            rightsum = maxsumfun(a, mid+1, right);
    
            int leftsum1 = 0;
            int lefts = 0;
            int i;
            for(i=mid; i>=left; i--)
            {
                lefts += a[i];
                if(lefts > leftsum1)
                    leftsum1 = lefts;
            }
    
            int rightsum1 = 0;
            int rights = 0;
            for(i=mid+1; i<=right; i++)
            {
                rights += a[i];
                if(rights > rightsum1)
                    rightsum1 = rights;
            }
    
            midsum = leftsum1 + rightsum1;
            if(midsum < leftsum)
                maxsum = leftsum;
            else
                maxsum = midsum;
            if(maxsum < rightsum)
                maxsum = rightsum;
        }
        return maxsum;
    }
    
    void getData(int d[], int n)
    {
        time_t t;
        srand((unsigned) time(&t));  /* 设置随机数起始值 */
    
        int i;
        for(i=0; i < n; i++)
            d[i] = rand() % 30 - 10; /* 获得-10--20之间的整数值 */
    }

    关键代码:

    // 递归计算最大子段
    int maxsumfun(int a[], int left, int right)
    {
        int maxsum = 0;
    
        if(left == right)
        {
            if(a[left] > 0)
                maxsum = a[left];
            else
                maxsum = 0;
        }
        else
        {
            int mid, leftsum, rightsum, midsum;
    
            mid = (left + right) / 2;
            leftsum = maxsumfun(a, left, mid);
            rightsum = maxsumfun(a, mid+1, right);
    
            int leftsum1 = 0;
            int lefts = 0;
            int i;
            for(i=mid; i>=left; i--)
            {
                lefts += a[i];
                if(lefts > leftsum1)
                    leftsum1 = lefts;
            }
    
            int rightsum1 = 0;
            int rights = 0;
            for(i=mid+1; i<=right; i++)
            {
                rights += a[i];
                if(rights > rightsum1)
                    rightsum1 = rights;
            }
    
            midsum = leftsum1 + rightsum1;
            if(midsum < leftsum)
                maxsum = leftsum;
            else
                maxsum = midsum;
            if(maxsum < rightsum)
                maxsum = rightsum;
        }
        return maxsum;
    }


  • 相关阅读:
    Centos常用快捷键
    ngnix笔记
    转载申明
    Linux 最小安装常用包
    update-alternatives关键解疑
    使用Java语言开发机器学习框架和参数服务器
    storm实践
    JVM线程状态,park, wait, sleep, interrupt, yeild 对比
    PHP版本解密openrtb中的价格
    Minimum Path Sum
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7564945.html
Copyright © 2011-2022 走看看