软件工程第三次作业——最大连续子数组和
一.问题及方法:
1.问题:
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n
例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。-- 引用自《百度百科》
2.方法:
思路一:暴力枚举
求一个数组的最大子数组和,如此序列{1, -2, 3, 10, -4, 7, 2, -5},我想最最直观也是最野蛮的办法便是,三个for循环三层遍历,求出数组中每一个子数组的和,最终求出这些子数组的最大的一个值。
思路二:
当前面的几个数,加起来后,b<0后,把b重新赋值,置为下一个元素,b=a[i]。当b>sum,则更新sum=b;若b<sum,则sum保持原值,不更新。
二.代码运行以及测试
由于技术有限,选择思路一暴力枚举法完成实验
流程图:
用Markdown画的流程图不好使,心态已崩:
graph TD
A(开始)-->B(sum=0)
B-->C[i=0,j,k]
C-->D{i < n?}
D-->|yes|E[j=1]
E-->F{i < 1?}
F-->|yes|G[ThisSm=0 k=i]
G-->H{k < j?}
H-->|yes|I[ThisSm+=A]
I-->J{ThisSm>sum?}
J-->|no|K[k++]
H-->|no|W[j++]
W-->F
K-->G
J-->|yes|L[sum=ThisSm]
L-->K
D-->|no|X[返回sum]
X-->Y(结束)
F-->|no|Z[i++]
Z-->D
代码:
package wzg2;
import java.util.Scanner;
public class Wzg2
{
static Scanner in = new Scanner(System.in);
static int max=0;
static int [] num =new int [1024];
public static void main(String[] args)
{
int r=0;
while(in.hasNextInt()){
num[r++]=in.nextInt();
}
calSum();
System.out.println("最大子段和为:"+max);
}
public static int choosedNSum(int start,int n)
{
int sum=0;
for(int i=start;i<start+n;i++)
{
sum=sum+num[i];
}
return sum;
}
public static void calSum()
{
int sum=0;
for(int i=1;i<=num.length;i++)
{
for(int j=0;j<=num.length-i;j++)
{
sum=choosedNSum(j,i);
if(sum>max){
max=sum;
}
}
}
if(max<=0){
max=0;
}
}
public static Object ceshi(int[] origanl) {
num = origanl ;
calSum();
return max;
}
}
运行:
进行测试:
接下来就是选择合适的覆盖方法进行测试,看看代码内部是否还有隐藏的问题。
测试工具选择的是JUnit,覆盖方式选择的是判定覆盖!
测试结果正确,错误测试显示错误
测试结束