Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 535|回复: 0

[算法学习]数组(序列)的最大子段和。

[复制链接]
  • TA的每日心情
    开心
    2021-3-12 23:18
  • 签到天数: 2 天

    [LV.1]初来乍到

    发表于 2014-12-2 00:06:36 | 显示全部楼层 |阅读模式
    问题描述:  有n个数(以下都视为整数),每个数有正有负,现在要在n个数中选取相邻的一段,使其和最大,输出最大的和。 问题分析:  看到这个问题,它是属于带“最”字的问题,其实就是一个求最优解的问题。对于这种问题的朴素算法就是枚举出每种可能,然后在其中寻找一个最优的解,然后输出。因为输出仅要求这个子段的和,因此不必再记录关于解的组成的信息。

    网上有很多方法,这里选二种。

    另附一个可以输出解的具体数据。
      
       
       
         
       

         
       
      
       一、穷举法:

    1. import java.util.*;
    2. public class LargestSubsegmentSum1
    3. {
    4. public static void main(String[] args)
    5. {
    6.   /**
    7.    *从键盘输入所要求的序列的长度n
    8.    */
    9.   Scanner in=new Scanner(System.in);
    10.   
    11.   System.out.println("Please enter the length of segment you want to make(输入你要求的序列的长度):");
    12.   int n=in.nextInt();
    13.   /**
    14.    *从键盘输入所要求的序列,存储在a[n]中
    15.    */
    16.   int[] a=new int[n];
    17.   System.out.println("Now,please enter the elements of the segment you want(请依次输入这个序列包含的元素(整数)):");
    18.   for(int i=0;i< n;i++)
    19.   {
    20.    a[i]=in.nextInt();
    21.   }
    22.   
    23.         double startTime=System.currentTimeMillis();//starttime
    24.         /**
    25.    *求解最大子段和存在maxSum中
    26.    */
    27.   int maxSum=a[0];
    28.   for(int i=0;i< n-1;i++)
    29.   {
    30.    int temp=a[i];
    31.    for(int j=i+1;j< n;j++)
    32.    {
    33.     temp+=a[j];
    34.     if(temp>maxSum)
    35.      maxSum=temp;
    36.    }
    37.   }
    38.   double endTime=System.currentTimeMillis();//endtime
    39.   /**
    40.    *打印输出求解结果和程序所用时间
    41.    */
    42.   System.out.println("The largest sub-segment sum is(最大子段和是):"+maxSum);
    43.   System.out.println("Basic Statements take(基本语句用时) "+(endTime-startTime)+" milliseconds!");
    44. }
    45. }
    复制代码
    二、动态规划
        我们令一个数组b,b[j]表示前j个元素能组成的最大和。如果b[j-1]大于零,则不管a[j]的情况, b[j-1]都可以向正方向影响,因此可以将a[j]加在b[j-1]上。如果b[j-1]小于零,则不管a[j]再大, 都会产生负影响,因此我们还不如直接令b[j]=a[j]。


    1. import java.util.*;
    2. public class LargestSubsegmentSum3
    3. {
    4. public static void main(String[] args)
    5. {
    6.   /**
    7.    *从键盘输入所要求的序列的长度n
    8.    */
    9.   Scanner in=new Scanner(System.in);
    10.   
    11.   System.out.println("Please enter the length of segment you want to make(输入你要求的序列的长度):");
    12.   int n=in.nextInt();
    13.   /**
    14.    *从键盘输入所要求的序列,存储在a[n]中
    15.    */
    16.   int[] a=new int[n];
    17.   System.out.println("Now,please enter the elements of the segment you want(现在请依次输入这个序列包含的元素(整数)):");
    18.   int i;
    19.   for(i=0;i< n;i++)
    20.   {
    21.    a[i]=in.nextInt();
    22.   }
    23.   /**
    24.    *求解最大子段和存在maxSum中
    25.    */
    26.   double startTime=System.currentTimeMillis();//starttime
    27.   int maxSum=0;
    28.   /* 我们令一个数组b,b[j]表示前j个元素能组成的最大和。如果b[j-1]大于零,则不管a[j]的情况,
    29.    * b[j-1]都可以向正方向影响,因此可以将a[j]加在b[j-1]上。如果b[j-1]小于零,则不管a[j]再大,
    30.    * 都会产生负影响,因此我们还不如直接令b[j]=a[j]。
    31.    */
    32.   int[] b=new int[n];
    33.   b[0]=a[0];
    34.   for(int j=1;j< n;j++)
    35.   {
    36.    if(b[j-1]>0)
    37.     b[j]=b[j-1]+a[j];
    38.    else
    39.    {
    40.     b[j]=a[j];
    41.    }
    42.    if(b[j]>maxSum)
    43.     maxSum=b[j];
    44.   }
    45.   
    46.   double endTime=System.currentTimeMillis();//endtime
    47.   /**
    48.    *打印输出结果和程序运行所用时间
    49.    */
    50.   System.out.println("The largest sub-segment sum is(最大子段和是):"+maxSum);
    51.   System.out.println("Basic Statements take(基本语句用时) "+(endTime-startTime)+" milliseconds!");
    52. }
    53. }
    复制代码
    三:可以输出解的具体组成信息

    1. /**
    2. * @author Wang Ke
    3. *
    4. */
    5. /**
    6. * 动态规划方法:若记b[j]为从a[i]到a[j]的最大的子段和 (j是定的,“最大”指的是i从1到j-1中,a[i]+...+a[j]最大的),
    7. * 那么所求的max{ a[i]+a[i+1]+...+a[j-1]+a[j] (1<=i< j<=n) } =max{ max{
    8. * a[i]+..+a[j] (1<=j<=n) } } =max{ b[1],...,b[n] }。 b[]由定义可知:j==1时,b[1]=a[1];
    9. * j>1时,b[j]=max{ b[j-1]+a[j],a[j] }。
    10. *
    11. */
    12. public class MaxArray {
    13.         /**
    14.          * @param a
    15.          */
    16.         public static void prtArray(int[] a) {
    17.                 for (int i = 0; i < a.length; i++) {
    18.                         System.out.print(a[i] + " ");
    19.                 }
    20.                 System.out.print("
    21. ");
    22.         }
    23.         /**
    24.          * @param a1
    25.          * @param a2
    26.          * @return
    27.          */
    28.         public static int max(int a1, int a2) {
    29.                 if (a1 >= a2 || a1 == a2)
    30.                         return a1;
    31.                 return a2;
    32.         }
    33.         /**
    34.          * @param n
    35.          * @param b
    36.          * @param a
    37.          * @param beg
    38.          */
    39.         public static void setB(int n, int[] b, int[] a, int[] beg) {
    40.                 if (n == 0) {
    41.                         b[n] = a[n];
    42.                         beg[n] = n;
    43.                 } else {
    44.                         setB(n - 1, b, a, beg);
    45.                         b[n] = max(b[n - 1] + a[n], a[n]);
    46.                         if (b[n - 1] + a[n] > a[n])
    47.                                 beg[n] = beg[n - 1];
    48.                         else
    49.                                 beg[n] = n;
    50.                 }
    51.         }
    52.         /**
    53.          * @param a
    54.          */
    55.         public static void maxChildArry(int[] a) {
    56.                 int b[] = new int[a.length];
    57.                 int beg[] = new int[a.length];
    58.                 b[0] = a[0];
    59.                 for (int n = 0; n < b.length; n++)
    60.                         setB(n, b, a, beg);
    61.                 int maxsum = b[getMaxElementIndex(b)];
    62.                 System.out.println("MaxSum: " + maxsum);
    63.                 PrtMaxChildArry(a, beg[getMaxElementIndex(b)], getMaxElementIndex(b));
    64.         }
    65.         /**
    66.          * @param aa
    67.          * @param beg
    68.          * @param end
    69.          */
    70.         public static void PrtMaxChildArry(int aa[], int beg, int end) {
    71.                 System.out.print("The Maxmium Child-Array is: { ");
    72.                 for (int i = beg; i <= end; i++) {
    73.                         System.out.print(aa[i] + " ");
    74.                 }
    75.                 System.out.println("}
    76. ");
    77.         }
    78.         /**
    79.          * @param b
    80.          * @return
    81.          */
    82.         public static int getMaxElementIndex(int[] b) {
    83.                 // TODO Auto-generated method stub
    84.                 int maxele = 0;
    85.                 int i;
    86.                 for (i = 1; i < b.length; i++) {
    87.                         if (b[maxele] < b[i]) {
    88.                                 maxele = i;
    89.                         }
    90.                 }
    91.                 return maxele;
    92.         }
    93.         /**
    94.          * @param args
    95.          */
    96.         public static void main(String[] args) {
    97.                 // TODO Auto-generated method stub
    98.                 int[] a = { 1, 2, -1, 1, 3, 2, -2, 3, -1, 5, -7, 3, 2, -2, 4 - 5 };
    99.                 prtArray(a);
    100.                 maxChildArry(a);
    101.         }
    102. }
    复制代码
    运行:
      C:ww>java MaxArray
    1 2 -1 1 3 2 -2 3 -1 5 -7 3 2 -2 -1
    MaxSum: 13
    The Maxmium Child-Array is: { 1 2 -1 1 3 2 -2 3 -1 5 }
      

      
      
       
       

         
       

         
       
      
    复制代码

    源码下载:http://file.javaxxz.com/2014/12/2/000635750.zip
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2025-2-25 04:07 , Processed in 0.401610 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表