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

一、设计思路

  之前我们已经写出了环形一维数组的最大子数组,现在我们只需要先随机出二维数组,将二维数组转化为一维数组,再调用这个求一维最大子数组的函数,即可求出结果。

  将二维数组转化为一维数组,再通过一维数组间接求出二维数组的最大子数组的方法与欢龙的方法异曲同工。我的方法是以一行为起点,然后从这一行一直加到最后一行,每加一行即产生可以向一维数组函数传递的一维数组。起始行依次向下递增,一直到最后一行。

二、代码

  1 //环形一维数组求最大子数组
  2 package erwei;
  3 
  4 public class oneArray {
  5 
  6     private int i;
  7     public static int maxS;
  8     public int maxShou;
  9     public int maxWei;
 10     void getMax(int[] a,int n){
 11         boolean x = false;
 12         for(i = 0;i < n;i++)
 13         {
 14             if(a[i] >= 0)
 15             {
 16                 x = true;
 17                 break;
 18             }
 19         }
 20         
 21         int sum=0,s1=0,s2=0,loc=0,loc1=0;
 22         if(x == true)          //有正数的情况下
 23         {
 24             for(i = 0;i < n;i++)        //全部为正数的情况下
 25             {
 26                 s2 += a[i];
 27                 if(a[i] >= 0)
 28                     sum += a[i];
 29                 if(sum == s2)
 30                 {
 31                     s2 = sum;
 32                     loc1 = n;
 33                 }
 34                 else
 35                     break;
 36             }
 37             if(a[0]>=0)            //默认的开头第一个数即为正数
 38             {
 39                 sum=a[0];
 40                 for(i=1;i<n;i++)
 41                 {
 42                     if(a[i]>=0)
 43                     {
 44                         sum+=a[i];
 45                     }
 46                     else
 47                     {
 48                     if(sum>=s1)
 49                         s1=sum;
 50                     loc=i;
 51                     if(a[i]<0)
 52                         sum=0;
 53                     break;
 54                     }
 55                 }
 56                 
 57                 int sum1=0;
 58                 for(i=0;i<n;i++)
 59                 {
 60                     if(a[i]>=0)
 61                     {
 62                         sum1+=a[i];
 63                     }
 64                     else 
 65                     {
 66                         if(sum1>=s2)
 67                         {
 68                             s2=sum1;
 69                             loc1=i;
 70                         }
 71                         if(a[i]<0)
 72                             sum1=0;
 73                     }
 74                 }
 75                 int s3=0,loc2=0;
 76                 if(a[n-1]>=0)
 77                 {
 78                     sum=a[n-1];
 79                     for(i=n-2;i>=0;i--)
 80                     {
 81                         if(a[i]>=0)
 82                         {
 83                             sum+=a[i];
 84                         }
 85                         else{
 86                         s3=sum;
 87                         loc2=i;
 88                         break;}
 89                     }
 90                 }
 91                 int s4=s1+s3;
 92                 if(s2>=s4)
 93                 {
 94                     maxS = s2;
 95                     maxShou = 0;
 96                     for(i=0;i<loc1;i++)
 97                     {
 98                         if(a[i]>0)
 99                         {
100                             maxWei = i;
101                         }
102                         else 
103                             break;
104                     }
105                     /*
106                     System.out.print("最大子数组和为:"+s2);
107                     System.out.println();
108                     System.out.println("子数组为:");
109                     for(i=0;i<loc1;i++)
110                     {
111                         if(a[i]>0)
112                         {
113                             System.out.print(a[i]+"\t");
114                         }
115                         else 
116                             break;
117                     }
118                     */
119                 }
120                 else 
121                 {
122                     maxS = s4;
123                     maxShou = loc2 + 1;
124                     maxWei = loc - 1;
125                     /*
126                     System.out.print("最大子数组和为:"+s4);
127                     System.out.println();
128                     System.out.println("子数组为:");
129                     for(i=0;i<loc;i++)
130                     {
131                          System.out.print(a[i]+"\t");
132                     }
133                     for(i=n-1;i>loc2;i--)
134                     {
135                         System.out.print(a[i]+"\t");
136                     }
137                     */
138                 }
139             }
140             else                  //默认的开头第一个数为负数
141             {
142                 sum=0;
143                 for(i=0;i<n;i++)
144                 {
145                     if(a[i]>=0)
146                     {
147                         sum+=a[i];
148                         if(i==n-1&&sum>s1)
149                             s1=sum;
150                             loc=i;
151                     }
152                     else 
153                     {
154                         if(sum>=s1)
155                         {
156                             s1=sum;
157                             
158                         }
159                         if(a[i]<0)
160                             sum=0;
161                     }
162                 }
163                 maxS = s1;
164                 maxWei = loc;
165                 for(i=loc;i>=0;i--)
166                 {
167                     if(a[i]>0)
168                     {
169                         maxShou = i;
170                     }
171                     else 
172                         break;
173                 }
174                 /*
175                 System.out.println("lovc"+loc);
176                 System.out.print("最大子数组和为:"+s1);
177                 System.out.println();
178                 for(i=loc;i>=0;i--)
179                 {
180                     if(a[i]>0)
181                     {
182                         System.out.print(a[i]+"\t");
183                     }
184                     else 
185                         break;
186                 }
187                 */
188             }
189         }
190         else if(x == false)              //没有正数的情况下
191         {
192             int t = a[0];
193             for(i = 1;i < n;i++)
194             {
195                 if(a[i] > t)
196                 {
197                     t = a[i];
198                     maxShou = i;
199                     maxWei = i;
200                 }
201             }
202             maxS = t;
203             /*
204             System.out.print("最大子数组和为:"+t);
205             System.out.println();
206             System.out.println("子数组为:");
207             System.out.print(t);
208             */
209         }
210     }
211     public int getmaxS(){
212         return maxS;
213     }
214     public int getmaxShou(){
215         return maxShou;
216     }
217     public int getmaxWei(){
218         return maxWei;
219     }
220 }
221 //环形二维数组求最大子数组
222 package erwei;
223 
224 import java.util.*;
225 
226 public class twoArray extends oneArray{
227 
228     public static void main(String[] args) {
229         // TODO Auto-generated method stub
230 
231         Scanner sc = new Scanner(System.in);
232         
233         int max,min,numL,numR;
234         int i,j,t;
235         int shouL,shouR,weiL,weiR,maxTwo;
236         
237         System.out.println("请输入二维数组的行数和列数:");
238         numL = sc.nextInt();
239         numR = sc.nextInt();
240         
241         System.out.println("请输入数组元素取值范围(保证前一个值小于后一个值):");
242         min = sc.nextInt();
243         max = sc.nextInt();
244         
245         int[][] twoArray1 = new int[numL][numR];
246         int[] oneArray1 = new int [numR];
247         int LTop;
248         
249         System.out.println("该二维数组为:");                         //生成随机二维数组
250         for(i = 0;i < numL;i++)
251             for(j = 0;j < numR;j++){
252                 twoArray1[i][j] = min + (int)(Math.random()*(max - min));
253                 System.out.print(twoArray1[i][j] + "\t");
254                 if(j == numR - 1){
255                     System.out.println();
256                 }
257             }
258         
259         maxTwo = twoArray1[0][0];
260         shouL = 0;
261         shouR = 0;
262         weiL = 0;
263         weiR = 0;
264         
265         for(i = 0;i < numR;i++){                                    //一维数组赋初值
266             oneArray1[i] = 0;
267         }
268         System.out.println();
269         oneArray one = new oneArray();
270         for(LTop = 0;LTop < numL;LTop++){                          //二维数组合并为一维数组    
271             for(i = LTop;i < numL;i++){
272                 for(j = 0;j < numR;j++){
273                     oneArray1[j] += twoArray1[i][j];
274                 }
275                 one.getMax(oneArray1, numR);
276                 if(one.getmaxS() > maxTwo){
277                     maxTwo = one.getmaxS();
278                     shouL = LTop;
279                     shouR = one.getmaxShou();
280                     weiL = i;
281                     weiR = one.getmaxWei();
282                 }
283             }
284             for(t = 0;t < numR;t++){
285                         oneArray1[t] = 0;
286             }    
287         }
288         
289         System.out.println("环形二维数组最大子数组和为:");
290         System.out.println(maxTwo);
291         System.out.println("该最大子数组为:");
292         if(shouR > weiR){
293             for(i = shouL;i <= weiL;i++){
294                 for(j = shouR;j < numR;j++){
295                     System.out.print(twoArray1[i][j] + "\t");
296                 }
297                 for(j = 0;j <= weiR;j++){
298                     System.out.print(twoArray1[i][j] + "\t");
299                 }
300                 System.out.println();
301             }
302         }
303         else{
304             for(i = shouL;i <= weiL;i++){
305                 for(j = shouR;j <= weiR;j++){
306                     System.out.print(twoArray1[i][j] + "\t");
307                 }
308                 System.out.println();
309             }
310         }
311         
312         sc.close();
313     }
314 
315 }
View Code

三、设计过程

  在实现过程中,一开始使用接口,后来使用另建一个新类来调用,类的使用还更熟练一些。

  编写的过程中大概有一个半小时卡在了将二维转化为一维数组的过程。一开始的想法是:

  1)设出首行和末行,首行与末行在同一位置;

  2)先保持首行不变,求出首行到末行相加后的一维数组;

  3)末行依次递增到最后一行;

  4)当末行递增到最后一行后,首行向下一行,末行再回到与首行相同的位置,重复2),3)直到首行也到达最后一行。

  可怎么也求不出正确相加的一维数组,突然想到为什么要让末行变来变去,只要保持首行不变,末行一直加到最后一行,只不过每加一行就可以向一维数组传递,加到最后一行后就让首行向下移动即可,首行一直移动到最后一行。

四、实验结果

非负:

有正有负:

全负:

五、结对成员

  刘双渤、刘洪阳。

  思路:刘双渤、刘洪阳。

  编程:刘双渤、刘洪阳。

posted on 2015-04-23 21:46  的小逸  阅读(326)  评论(0编辑  收藏  举报