三、测试设计二:最大连续子序列函数
1、最大连续子序列函数介绍
给定一个整数数组,数组里可能有正数、负数和零。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值。例如,如果输入的数组为{1,-2,3,10,-4,7,2,-5},和最大的子数组为{3,10,-4,7,2},那么输出为该子数组的和18。
)1 输入一个数组num[a1,a2,…ai…an] ai为正整数 i ,n>=0
)2 输入之间的关系:
输入num[a1,a2,…ai…an] ai为整数 i ,n>=0 表示一个数组
单个之间: ai为整数; 1<=i<=n
两个之间: ai,aj为整数; 1<=i<=n 1<=j<=n
多个之间: ai,aj,ak为整数; 1<=i<=n 1<=j<=n 1<=k<=n
)3 输出之间的关系:
输出为子序列相加的和的最大数,sum>=0,sum为正整数
输出与输入之间的关系:
当输入num中没有值时输出为0;
当输入num中只有一个数值a1的时候,输出sum=a1;
当输入中数值超过一个的时候,sum为连续一个或多个数组组成的子数组和的最大值
sum1=a1, sum2=a1+a2, sum3=a1+a2+…+ai+… , sumi=ai+a(i+1)+…. sum=ai+…+aj+…+ak+…. i ,j ,k都是连续正整数 并且k>=j>=i >=1
sum>=sum1>=sum2>=sum3>=sumi 输出sum
2、用例设计
输入用例:[-1,0,1,2,-1,-4]
预期输出:3
输入用例:[-2,2,1,2,3,-5,9]
预期输出:12
输入用例:[1,2]
预期输出:[3]
输入用例:[1]
预期输出:[1]
输入用例:[]
预期输出:[]
3、bug用例分析
3.31、源代码
package test2;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class test {
public static int maxSubSum2(int[] a) {
int maxSum = 0;
for (int i = 0; i < a.length; i++) { //bug1将for (int i = 0; i < a.length; i++) 改成for (int i = 1; i < a.length; i++)导致每次遍历都遍历不到a数组中第一个数,最后的结果可能会偏小。
int tempSum = 0;
for (int j = i; j < a.length; j++) { // bug2将 for (int j = i; j < a.length; j++)改成for (int j = i; j <= a.length; j++) 更改代码导致j遍历数组时最后一个j=a.length超出数组范围代码报错
tempSum += a[j];
maxSum = maxSubSum(tempSum,maxSum);
}
//将maxSum = maxSubSum(tempSum);放在这里将导致maxSum输出偏小,出现bug
}
return maxSum;
}
public static int maxSubSum(int tempSum,int maxSum) {
if (tempSum > maxSum) {
return tempSum;
}
else {
return maxSum;
}
}
public static void main(String[] arg){
int[] a = {-1,0,1,2,-1,-4};
int sum = test.maxSubSum2(a);
System.out.println(sum);
}
}
junit测试代码
package test2;
import static org.junit.Assert.*;
import org.junit.Test;
import com.sun.org.apache.xpath.internal.operations.Plus;
public class testTest {
public static test Plus = new test();
public int ans;
@Test
public void test() {
int[] a = {-1,0,1,2,-1,-4};
ans = test.maxSubSum2(a);
assertEquals(3, ans);
}
@Test
public void test1() {
int[] a = {2,8};
ans = test.maxSubSum2(a);
assertEquals(10, ans);
}
@Test
public void test2() {
int[] a = {1};
ans = test.maxSubSum2(a);
assertEquals(1, ans);
}
@Test
public void test3() {
int[] a = {};
ans = test.maxSubSum2(a);
assertEquals(0, ans);
}
@Test
public void test4() {
int[] a = {-2,2,1,2,3,-5,9};
ans = test.maxSubSum2(a);
assertEquals(12, ans);
}
}
图一 最大连续子序列源代码
for (int i = 0; i < a.length; i++)
图2 bug1代码 9行
for (int j = i; j < a.length; j++)
图3 bug2代码 12行
maxSum = maxSubSum(tempSum,maxSum);
图4 bug3代码 14行
3.3.2bug1分析
//bug1将for (int i = 0; i < a.length; i++) 改成for (int i = 1; i < a.length; i++)导致每次遍历都遍历不到a数组中第一个数,最后的结果可能会偏小。未考虑数组最后一个数。
3.3.3bug2分析
// bug2将 for (int j = i; j < a.length; j++)改成for (int j = i; j <= a.length; j++) 更改代码导致j遍历数组时最后一个j=a.length超出数组范围代码报错。
3.3.4bug3分析
将第14行代码移到第16行没有考虑到中间数的相加,导致最后得出的结果偏小。