zoukankan      html  css  js  c++  java
  • 求一个序列的连续子列和的最大值

    比较结果

    下面值四中算法的的执行时间:

    当n的长度为100
    ygh.study.algorithm.Demo2.MaxSubSequence1 execute time: 4
    ygh.study.algorithm.Demo2.MaxSubSequence2 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为1000
    ygh.study.algorithm.Demo2.MaxSubSequence1 execute time: 115
    ygh.study.algorithm.Demo2.MaxSubSequence2 execute time: 4
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为10000
    ygh.study.algorithm.Demo2.MaxSubSequence1 execute time: 67527
    ygh.study.algorithm.Demo2.MaxSubSequence2 execute time: 28
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0


    因为第第一中算法 n^3 太消耗时间,为了比较下面三种算法,下面的测试中把N的值增大,把第一个算法的执行注释掉:

    当n的长度为100
    ygh.study.algorithm.Demo2.MaxSubSequence2 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为1000
    ygh.study.algorithm.Demo2.MaxSubSequence2 execute time: 3
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为10000
    ygh.study.algorithm.Demo2.MaxSubSequence2 execute time: 24
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 1
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为100000
    ygh.study.algorithm.Demo2.MaxSubSequence2 execute time: 2248
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为1000000
    ygh.study.algorithm.Demo2.MaxSubSequence2 execute time: 240431
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 1
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 1

    因为第二种算法n^2也很慢,为了比较分而治之和在线算法的优劣,下面的比较把复制度为n^2的算法注释掉,继续增加N的值

    当n的长度为100
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 1
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为1000
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为10000
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 1
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 0
    当n的长度为100000
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 0
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 1
    当n的长度为1000000
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 1
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 1
    当n的长度为10000000
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 9
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 10
    当n的长度为100000000
    ygh.study.algorithm.Demo2.MaxSubSequence4 execute time: 143
    ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: 148

    感觉在线算法并不是比分而治之算法要要厉害太多,就差几个毫秒

    下面是具体的代码实现

      1 package ygh.study.algorithm;
      2 
      3 import algorithms.self.tools.IntegerArrayTools;
      4 import algorithms.self.tools.MethodExecuteTimeUtils;
      5 
      6 /**
      7  * 现在有一个序列{A1,A2,A3,...,An} 求他的子列和的最大值 求f(i,j)=max{0,sum(i,j)Ak}
      8  * 
      9  * @author ygh 2017年3月18日
     10  */
     11 public class Demo2 {
     12 
     13     public static void main(String[] args) throws Exception {
     14         for(int i=100;i<=100000000;i=i*10){
     15             System.out.println("当n的长度为"+i);
     16             int[] arr = IntegerArrayTools.getRandomArray(i, i);
     17             Class<?>[] types ={int[].class};
     18             Object[] params={arr};
     19             Demo2 bean = new Demo2();
     20             MethodExecuteTimeUtils.getMethodExecuteTime(bean, params, "MaxSubSequence1", types,true);
     21             MethodExecuteTimeUtils.getMethodExecuteTime(bean, params, "MaxSubSequence2", types,true);
     22             MethodExecuteTimeUtils.getMethodExecuteTime(bean, params, "MaxSubSequence4", types,true);
     23             long start = System.currentTimeMillis();
     24             MaxSubSequence4(arr);
     25             long end = System.currentTimeMillis();
     26             long take = end-start;
     27             System.out.println("ygh.study.algorithm.Demo2.MaxSubSequence3 execute time: "+take);
     28         }
     29         
     30         //测试正确性,因为我的数组都是整数,最大子列和应该是所有项数之和
     31 //        int maxSubSquence1 = MaxSubSequence1(arr);
     32 //        System.out.println(maxSubSquence1 == (IntegerArrayTools.getIntegrArraySum(arr)));
     33 //        int maxSubSquence2 = MaxSubSequence2(arr);
     34 //        System.out.println(maxSubSquence2 == (IntegerArrayTools.getIntegrArraySum(arr)));
     35 //        int maxSubSquence3 = MaxSubSequence3(arr,0,arr.length-1);
     36 //        System.out.println(maxSubSquence3 == (IntegerArrayTools.getIntegrArraySum(arr)));
     37 //        int maxSubSquence4 = MaxSubSequence4(arr);
     38 //        System.out.println(maxSubSquence4 == (IntegerArrayTools.getIntegrArraySum(arr)));
     39     }
     40 
     41     /**
     42      * 第一种算法,使用最暴力的for循环来技术子列和 因为有三重for循环,所以时间复杂度T(n)=O(n^3)
     43      * 
     44      * @param arr 需要计算最大子列和提供数据的数组
     45      * @return 如果最大子列和比0大,返回最大子列和,否则,返回0
     46      */
     47     public static int MaxSubSequence1(int arr[]) {
     48         int length = arr.length;
     49         int maxSubSequence = 0;
     50         int sum = 0;
     51         for (int i = 0; i < length; i++) {
     52             for (int j = i; j < length; j++) {
     53                 sum = 0;
     54                 for (int k = i; k <= j; k++) {
     55                     sum = sum + arr[k];
     56                 }
     57                 if (sum > maxSubSequence) {
     58                     maxSubSequence = sum;
     59                 }
     60             }
     61         }
     62         return maxSubSequence;
     63     }
     64 
     65     /**
     66      * 在第一种算法的基础之上,我们来做一次优化,我们发现,k循环,每次都会在计算相同的求和 而且每次求和都比上一次求和多算了一个a[j],那么我们为什么不使用一个临时变量去存储这个 累加的和?
     67      * 这样就可以去掉k循环,下面是代码的实现 这样函数时间复杂度T(n)=O(n^2)
     68      * 
     69      * @param arr 需要计算最大子列和提供数据的数组
     70      * @return 如果最大子列和比0大,返回最大子列和,否则,返回0
     71      */
     72     public static int MaxSubSequence2(int arr[]) {
     73         int length = arr.length;
     74         int maxSubSequence = 0;
     75 
     76         int sum = 0;
     77         for (int i = 0; i < length; i++) {
     78             sum = 0;
     79             for (int j = i; j < length; j++) {
     80                 sum = sum + arr[j];
     81                 if (sum > maxSubSequence) {
     82                     maxSubSequence = sum;
     83                 }
     84             }
     85         }
     86         return maxSubSequence;
     87 
     88     }
     89 
     90     public static int MaxSubSequence3(int arr[], int Left, int Right) {
     91         int MaxLeftSum, MaxRightSum;
     92         int MaxLeftBorderSum, MaxRightBorderSum;
     93         int LeftBorderSum, RightBorderSum;
     94         int center, i;
     95 
     96         if (Left == Right) {
     97             if (arr[Left] > 0)
     98                 return arr[Left];
     99             else
    100                 return 0;
    101         }
    102 
    103         center = (Left + Right) / 2;
    104         MaxLeftSum = MaxSubSequence3(arr, Left, center);
    105         MaxRightSum = MaxSubSequence3(arr, center + 1, Right);
    106 
    107         MaxLeftBorderSum = 0;
    108         LeftBorderSum = 0;
    109         for (i = center; i >= Left; i--) {
    110             LeftBorderSum += arr[i];
    111             if (LeftBorderSum > MaxLeftBorderSum)
    112                 MaxLeftBorderSum = LeftBorderSum;
    113         }
    114 
    115         MaxRightBorderSum = 0;
    116         RightBorderSum = 0;
    117         for (i = center + 1; i <= Right; i++) {
    118             RightBorderSum += arr[i];
    119             if (RightBorderSum > MaxRightBorderSum)
    120                 MaxRightBorderSum = RightBorderSum;
    121         }
    122         return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
    123     }
    124 
    125     private static int Max3(int a, int b, int c) {
    126         int max;
    127         max = a > b ? a : b;
    128         max = max > c ? max : c;
    129         return max;
    130     }
    131 
    132     /**
    133      * 在线算法,算法分析,从0到end依次遍历此数组 用maxSubSequence控制总的子列和 用currentSum控制当前的子列和。
    134      * 如果currentSum大于maxSubSequence,maxSubSequence = currentSum 如果currentSum小于0,直接舍弃。
    135      * 
    136      * @param arr
    137      * @return
    138      */
    139     public static int MaxSubSequence4(int arr[]) {
    140         int length = arr.length;
    141         int currentSum = 0, maxSubSequence = 0;
    142         for (int i = 0; i < length; i++) {
    143             currentSum = currentSum + arr[i];
    144             if (currentSum > maxSubSequence) {
    145                 maxSubSequence = currentSum;
    146             } else if (currentSum < 0) {
    147                 currentSum = 0;
    148             }
    149 
    150         }
    151         return maxSubSequence;
    152     }
    153 
    154 }
    View Code
  • 相关阅读:
    win10安装mysql5.6,mysql启动时,闪退
    java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
    textarea输入框随内容撑开高度
    jQuery插件写法
    .net APIHelper client获取数据
    .net XmlHelper xml帮助类
    .net JsonHelper json帮助类
    .net WebAPI返回xml、json格式
    VMware Workstation Pro 14 序列号
    embed标签 阻止点击事件 让父元素处理点击事件
  • 原文地址:https://www.cnblogs.com/yghjava/p/6576181.html
Copyright © 2011-2022 走看看