要求:随机输出一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。
实验安排:
整数数组求最大子数组: (计划安排) |
|
第一阶段: |
首先确定解题思路,大概实现简单的过程大纲,考虑各种不成立因素,进行第一部分的修改。 |
第二阶段: |
初步进行代码的实现,进行纠错改正,以保证大体思路正确,可以实现功能。 |
第三阶段: |
对程序进行优化修改,以保证运行效率等方面达到要求。 |
整数数组求最大子数组: (时间安排) |
|
周五: |
大体思路在草纸上写出,进行重要部分的详细书写,思路上的改正,形成解答思路。 |
周六: |
简单的上机实现,在环境中进行编译,以确定解题思路的正确与否。将整体过程完成,已初步实现整体功能。 |
周日: |
对程序进行优化改错,初步达到基本要求,重新审题,以确保不存在理解偏差。 |
周一: |
进行最后验证,完成表格及博客书写。 |
初步实现:(理解原因存在错误,未改正前)
对子数组的分组情况想的定义为一定的,后来检查过程中才理解到子数组的大小不确定,个数是任意的,就类似于一个集合的所有子集。
package 子数组大小;
import java.util.Scanner;
public class main {
/** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Scanner A=new Scanner(System.in); System.out.println("请输入数组长度和分组子数组长度:"); int n=A.nextInt(); int m=A.nextInt(); while(m>n){ System.out.println("输入有误,请重新输入:"); n=A.nextInt(); m=A.nextInt(); } System.out.println("请输入数组数值范围:"); int N=A.nextInt(); int M=A.nextInt(); int a[]=new int[n]; int b[]=new int[n-m+1]; int i; System.out.println("数组为:"); for(i=0;i<n;i++) { a[i]=N+(int)(Math.random()*(M-N)); System.out.print(a[i]+" "); } System.out.println(); int j,k,t; i=0; for(j=0;j<n-m+1;j++) { t=i; for(k=0;k<m;k++) { b[j]+=a[t]; t++; } i++; } System.out.println("各子数组大小:"); for(i=0;i<n-m+1;i++) { System.out.print(b[i]+" "); } int p=b[0]; int q=0; for(i=1;i<n-m+1;i++) { if(p<b[i]) { p=b[i]; q=i; } } System.out.println(" 本数组中子数组和最大的为:"+p); System.out.println("这个子数组是:"); for(i=0;i<m;i++) { System.out.print(a[q+i]+" "); }
}
}
改正后:
package 子数组更改;
import java.util.Scanner;
public class zsz {
/** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub
Scanner A=new Scanner(System.in); System.out.println("请输入数组长度:"); int n=A.nextInt(); System.out.println("请输入数组数值范围:"); int N=A.nextInt(); int M=A.nextInt(); int a[]=new int[n]; int b[][]=new int[n][n]; int i; System.out.println("数组为:"); for(i=0;i<n;i++) { a[i]=N+(int)(Math.random()*(M-N)); System.out.print(a[i]+" "); } System.out.println(); int j,k=n,t; for(i=0;i<n;i++) { for(j=0;j<k;j++) { for(t=j;t<j+i+1;t++) { b[i][j]+=a[t]; } } k--; } System.out.println("各子数组大小:"); for(i=0;i<n;i++){ for(j=0;j<n;j++){ System.out.print(b[i][j]+" "); } System.out.println(); } int p=b[0][0]; int q=0,r=0; for(i=0;i<n;i++) { for(j=0;j<n-i;j++) { if(p<b[i][j]) { p=b[i][j]; q=i; r=j; } } } System.out.println(" 本数组中子数组和最大的为:"+p); System.out.println("这个子数组是:"); for(i=0;i<q+1;i++) { System.out.print(a[r+i]+" "); }
}
}
将各子数组和的结果存放到二维数组中,每行数组存放不同的大小的子数组,依次从上到下为子数组个数从1到数组总个数;然后对二维数组进行比较以得到最大值,即和最大的子数组,对子数组元素进行输出。
缺陷记录表: |
|
1: |
a[i]=N+(int)(Math.random()*(M-N));拥有负数的随机数的产生,数值范围为N-M,根据通常行为写成a[i]=N+(int)(Math.random()*(M+N)),因为N为负数,这样一来随机数便为N到小于M的范围。 |
2: |
System.out.print(a[q+i]+" ");初步完成中子数组中数据的输出,在验证例子时习惯性定义为子数组个数为3,所以在输出时错误性的输出3个数。 |
3: |
最大的纠错为理解错误,初步完成中理解子数组的大小是自定义的,以至于整体造成大方向出现偏差。这就像软件工程中的问题,在软件交付过程中,制造方一定要认真理解客户所提出的要求,以免理解偏差造成不可低估的后果。 |
4: |
定义二维素组存放子数组和的大小,进行比较时,因为二维数组中一部分未用到,系统自定义为0,如果数组的取值范围为负数,则0将影响其比较结果,因此在比较时对未用的部分进行略过,这样避免了重复比较以及对结果的影响。 |