循环一维数组求最大子数组

题目:

随机出一个一维数组,设该数组为循环数组,求其最大小子数组。

一、设计思路

求最大子数组,就求出最大的连续正子数组。

将数组分为全负和有非负值两种情况。全负求出最大值即可。

在有非负值的情况下,先判断该随机数组的首尾是否相连,即首尾是否都大于等于零。如果首尾相连,则将该一维数组分为首、中、尾三部分,先求出首尾和S1,再求中间最大连续正子数组和S,令S1和S与maxS相比较,求出最大子数组;如果首尾不相连,则直接借鉴前一种情况中部的算法,求最大正子数组S。

二、源代码

  1 //刘双渤,刘洪阳,循环一维数组求最小子数组
  2 package zishuzu;
  3 import java.util.*;
  4
  5 public class zuidazishuju {
  6
  7     /**
  8      * @param args
  9      */
 10     public static void main(String[] args) {
 11         // TODO Auto-generated method stub
 12
 13         Scanner sc = new Scanner(System.in);
 14
 15         int n,max,min;
 16         int i;
 17         System.out.println("请输入一维数组的长度:");
 18         n = sc.nextInt();
 19         System.out.println("请输入该数组元素的取值范围(请保证前一个值小于后一个值):");
 20         min = sc.nextInt();
 21         max = sc.nextInt();
 22
 23         int[] a = new int[n];
 24
 25         for(i = 0;i < n;i++)
 26         {
 27             a[i] = min + (int)(Math.random()*(max-min));
 28         }
 29
 30         System.out.println("该一维循环随机数组为:");
 31         for(i = 0;i < n;i++)
 32         {
 33             System.out.print(a[i] + "\t");
 34         }
 35         System.out.println();
 36
 37         int maxS,shouS1 = 0,weiS1 = 0,shouS = 0,weiS = 0,S,S1;
 38         int js,midSta = 0,midSta1 = 0,loci;
 39         int[] loc = new int[n];
 40         int judge = 0;
 41
 42         for(i = 0;i < n;i++)                       //判断数组元素是否含有非负数
 43         {
 44             if(a[i] >= 0)
 45             {
 46                 judge = 1;
 47                 midSta1 = i;
 48                 break;
 49             }
 50         }
 51         maxS = a[0];
 52         S = 0;
 53         S1 = 0;
 54         js = 0;
 55         loci = 0;
 56         if(judge == 0)                             //所有元素小于零
 57         {
 58             for(i = 0;i < n;i++)
 59             {
 60                 if(a[i] > maxS)
 61                 {
 62                     maxS = a[i];
 63                     loci = 0;
 64                     loc[loci] = i+1;
 65                 }
 66                 else if(a[i] == maxS)
 67                 {
 68                     loci += 1;
 69                     loc[loci] = i +1;
 70                 }
 71             }
 72             System.out.println("最大子数组和为:" + maxS);
 73             System.out.println("数组第一个元素位置为\"1\"");
 74             System.out.print("最大子数组所在位置为:");
 75             for(i = 0;i <= loci;i++)
 76             {
 77                 System.out.print(loc[i] + " ");
 78             }
 79         }
 80         else                                      //正负同时存在
 81         {
 82             if(a[0] >= 0 && a[n - 1] >= 0)            //第一个元素和最后一个元素非负
 83             {
 84                 for(i = 0;i < n;i++)             //从0开始求第一个连续非负子数组
 85                 {
 86                     if(a[i] >= 0)
 87                     {
 88                         S1 += a[i];
 89                         weiS1 = i + 1;
 90                         if(i == n -1)
 91                         {
 92                             shouS1 = 1;
 93                         }
 94                     }
 95                     else
 96                     {
 97                         break;
 98                     }
 99                 }
100                 for(i = n - 1;i > weiS1;i--) //从n-1开始求连续非负子数组
101                 {
102                     if(a[i] >= 0)
103                     {
104                         S1 += a[i];
105                         shouS1 = i +1;
106                     }
107                     else
108                     {
109                         break;
110                     }
111                 }
112                 if(S1 >= maxS)                  //首尾相连子数组与maxS比较
113                 {
114                     maxS = S1;
115                     shouS = shouS1;
116                     weiS = weiS1;
117                 }
118                 for(i = weiS1;i < shouS1 - 1;i++)   //求中间第一个非负数
119                 {
120                     if(a[i] >= 0)
121                     {
122                         midSta = i;
123                         break;
124                     }
125                     else if(i == shouS1 - 2)
126                     {
127                         midSta = i + 1;
128                     }
129                 }
130                 for(i = midSta;i < shouS1 - 1;i++)     //求中间最大连续非负子数组
131                 {
132                     if(a[i] >= 0)
133                     {
134                         S += a[i];
135                         js++;
136                     }
137                     else
138                     {
139                         if(S >= maxS)
140                         {
141                             maxS = S;
142                             weiS = i -1;
143                             shouS = i -js;
144                             js = 0;
145                             S = 0;
146                         }
147                         else
148                         {
149                             S = 0;
150                             js = 0;
151                         }
152                     }
153                 }
154             }
155             else                                     //首尾不是连续非负子数组的情况
156             {
157                 for(i = midSta1;i < n;i++)     //求最大连续非负子数组
158                 {
159                     if(a[i] >= 0)
160                     {
161                         S += a[i];
162                         js++;
163                     }
164                     else
165                     {
166                         if(S >= maxS)
167                         {
168                             maxS = S;
169                             weiS = i ;
170                             shouS = i -js + 1;
171                             js = 0;
172                             S = 0;
173                         }
174                         else
175                         {
176                             S = 0;
177                             js = 0;
178                         }
179                     }
180                 }
181             }
182             System.out.println("最大子数组和为:" + maxS);
183             System.out.println("数组第一个元素位置为\"1\"");
184             System.out.println("最大子数组首位置为:" + shouS);
185             System.out.println("最大子数组尾位置为:" + weiS);
186         }
187         sc.close();
188     }
189
190 }

三、设计过程

先给出随机一维子数组,然后分情况完成。

全负情况比较简单,但考虑到有相同最大值存在的情况,于是建立一个一维数组loc[n]来保存相同最大值的位置。验证时,发现多最大值的情况下总是为在输出的位置的最前边多一个,修改初始值解决。

有非负值情况下,在计算首尾和S1时,如果数组全正,则有可能S1为实际值的两倍,因此根据weiS1来判断首尾位置,避免重复相加。在设计中间部分是,如何跳过负值和保存判断最大子数组和是关键,一开始的想法是在出现第一个非负值的情况下保存判断最大子数组和,并将S,js初始化为0,逻辑上不知没有找出错误,最后使用的方法是在每一个负值出现时就判断保存和初始化,成功。

四、实验结果:

有非负值存在且首尾相连:

有非负值且首尾不想连:

全正:

全负:

五、结组成员

刘双渤,刘洪阳。

共同完成设计思路。

时间: 2024-10-25 08:10:15

循环一维数组求最大子数组的相关文章

一维数组求最大子数组(解决溢出问题)

一.题目要求 题目:返回一个整数数组中最大子数组的和. 要求: 要求程序必须能处理1000 个元素: 每个元素是int32 类型的: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.设计思想 程序在宏里面定义出了数组长度的大小,在长度超过100万的时候程序直接崩溃,其实这并不是因为结果太大导致的数值溢出,而是因为内存溢出,我们的数组是定义在程序内部的,属于局部变量,存放位置在栈上

环形数组求最大子数组之和

环形数组求最大子数组之和: 实验要求: 随机产生一个整形数组,假设首尾相连为环形,求其相连的字数组的和,并输出子数组的元素. 设计思路: 因为是环形,所以要考虑自设的头尾的情况,在此分为两大类考虑,一种为数组中存在正数情况,一种为全部为负数的情况: 在存在正数的情况中又可分为三种情况,一种为全部为正数的情况,一种为自设的头元素为正数,最后一种为自设的头元素为负数.根据这几种情况分类进行实现. 在实现过程中,对数组元素从头到尾进行遍历,如果遇到正数即用和相加,直到相邻的下一个为负数,即存放目前该最

二维环形数组求最大子数组和

一.要求 1.题目: 返回一个二维数组中最大子数组的和. 2.要求: 输入一个二维整形数组,数组里有正数也有负数. 二维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 求所有子数组的和的最大值.要求时间复杂度为O(n). 3.结对开发要求: 两人结对完成编程任务. 一人主要负责程序分析,代码编程. 一人负责代码复审和代码测试计划. 发表一篇博客文章讲述两人合作中的过程.体会以及如何解决冲突(附结对开发的工作照). 二.设计思路 1.从键

循环数组求最大子数组

一.题目要求 题目:返回一个整数数组中最大子数组的和. 要求: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值.要求时间复杂度为O(n). 二.设计思想 把数组每一位向后移动一位,最后一位放在第一位.循环多次,每次求其最大子数组,存放到新数组内,比较新数组中最大数,

结对开发--四实现循环二维数组求最大子数组的和

一.实现思路 再上一个实验基础上加上环,我们实现环的思想是每一列依次向此替换,直至替换出能出现的所有的二维数组,再用上一个求最大子数组的方法全部实现 二.实验代码 package com.minirisoft; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.Scanner; public class HuanTwoArray { public stat

一维数组求最大子数组的和(首位相邻32位)

返回一个整数数组中最大子数组的和,细化分析:1,在所有以元素tail结尾的子数组中,选出元素和最大的子数组,tail=1,2...n.2,以元素k结尾的和最大的子数组是包含以元素tail-1结尾的和最大的子数组还是就只有元素tail这一个元素,一共有这两个可选状态. 3,在得到以每个元素结尾的和最大的子数组之后,只要取其中最大值就是所有子数组中最大的子数组 4,将数组元素的类型定义为_int32,数组元素随机产生. 代码如下: //李妍 王硕 2016.3.25 #include <iostre

结对开发——环形一维数组求最大子数组和

题目:返回一个整数数组中最大子数组的和.要求:(1)输入一个整形数组,数组里有正数也有负数.(2)数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.(3)如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大.(4)同时返回最大子数组的位置.(5)求所有子数组的和的最大值.要求时间复杂度为O(n).一.设计思想 这个问题的最优解一定是以下两种可能.可能一:最优解没有跨过array[n-1]到array[0],即和非环形数

整数数组求最大子数组和

一.实验题目 返回一个整数数组中最大子数组的和. 二.实验要求 输入一个一维整形数组,数组里有正数也有负数. 一维数组首尾相接,象个一条首尾相接带子一样. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和.求所有子数组的和的最大值. 三.设计思想 该实验大部分可以分为两部分: 1.利用while循环录入输入的数组值,输入值为string类型,利用Integer.parseInt(String a),存入int数组,如果是"#"则结束录入 2.调用求最大值函数和的最大值,分

结对开发,首位相邻的数组求最大子数组

结对人员:张世通 梁世豪 一.题目 返回一维数组中最大子数组的和 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和. 如果数组A[0]……A[j-1]首尾相邻,允许A[i-1], …… A[n-1], A[0]……A[j-1]之和最大. 同时返回最大子数组的位置. 求所有子数组的和的最大值. 要求时间复杂度为O(n) 二.设计思路 1.在上一次求一维数组最大子数组的问题上,进行拓展,继续使用类似的求和方法 2.通过定义变量start,fin