软件工程第三次作业

Posted 你是毅强吧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了软件工程第三次作业相关的知识,希望对你有一定的参考价值。


求子段最大和问题


一、问题描述

问题: 给定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。


求解:关于求最大子段和的问题,本次运用暴力求解、暴力求解的优化、
分治算法、遍历算法四种方法进行求解。


二、程序算法

public class getMaxpd {
    /*
     * 暴力求解法
     * 
     * 列举出所有的字段和、选出最大字段和
     * 
     * Run Time O(N^3)
     */
    public static int getMaxpd1(int[] arr){
        int maxSum = 0;
        for(int i = 0; i < arr.length;i++) {
            for(int j = i; j < arr.length;j++) {
                int sum = 0;
                for(int k = i; k <= j;k++) {
                    sum += arr[k];
                }
                if(sum > maxSum) {
                    maxSum = sum;
                }
            }
        }
        return maxSum;
    }
    
    /*
     * 暴力求解法的改进
     * 
     * 去掉最后一次的循环过程
     * 
     * Run Time O(N^*2)
     */
    public static int getMaxpd2(int[] arr) { 
        int maxSum = 0;
        for(int i = 0; i < arr.length; i++) {
            int sum = 0;
            for(int j = i; j < arr.length;j++) {
                sum += arr[j];
                if(sum > maxSum) {
                    maxSum = sum;
                }
            }
        }
        return maxSum;
    }
    
    /*
     * 分治算法三种情况:
     * 1.最大的字段存在center以左
     * 2.最大的字段存在center以右
     * 3.最大的字段存在包括center的连续部分
     * 
     * 找出后判断最大部分,用递归进行寻找
     * Run Time O(N*logN)
     */
    public static int getMaxpd3(int[] arr,int left,int right) {
        if (left == right) {  
            if (arr[left] > 0) {  
                return arr[left];  
            } else {  
                return 0;  
            }  
        }  
        int center = (left+right)/2;
        int maxLeftSum = getMaxpd3(arr,left,center);
        int maxRightSum = getMaxpd3(arr,center+1,right);
        
        //left-half‘s  sum
        int maxLeftAsideSum = 0,
            leftAsideSum = 0;
        for(int i = center; i >= left; i--) {
            leftAsideSum += arr[i];
            if(leftAsideSum > maxLeftAsideSum) {
                maxLeftAsideSum = leftAsideSum;
            }
        }
        //right-half‘s sum
        int maxRightAsideSum = 0,
            rightAsideSum = 0;
        for(int i = center+1;i <= right; i++) {
            rightAsideSum += arr[i];
            if(rightAsideSum > maxRightAsideSum) {
                maxRightAsideSum = rightAsideSum;
            }
        }
        
        //has center sum
        int centerSum = maxLeftAsideSum + maxRightAsideSum;
        
        if(maxLeftSum > maxRightSum && maxLeftSum > centerSum) {
            return maxLeftSum;
        }else if (maxRightSum > maxLeftSum && maxRightSum > centerSum) {
            return maxRightSum;
        }else {
            return centerSum;
        }
        
    }
    
    /*
     * 从Array的某一点,寻找到Array[i]的最大字段
     * 置需要遍历一次数组
     * Run Time O(N) 
     * The best in my functions
     */
    public static int getMaxpd4(int arr[]) {
        int maxSum =0,
            sum = 0;
        for(int i = 0; i < arr.length; i++) {
            sum += arr[i];
            if(sum > maxSum) {
                maxSum = sum;
            }else if(sum < 0) {
                sum = 0;
            }
        }
        return maxSum;
    }
    
}

三、测试

(1)条件判定测试部分核心代码

public class getMaxpdTest {

    @Test
    public void testGetMaxpd0() { 
        int arr[] = {1,2,3,4,5,6};//全正用例
        assertEquals(21,new getMaxpd().getMaxpd4(arr));
    }

    @Test
    public void testGetMaxpd1() { 
        int arr[] = {1,2,-5,3,-15,4,5,-5,-1,2};//测试用例
        assertEquals(9,new getMaxpd().getMaxpd4(arr));
    }

    @Test
    public void testGetMaxpd2() {
        int arr[] = {-1,-2,-100,-10};//全负测试用例
        assertEquals(0,new getMaxpd().getMaxpd4(arr));
    }

    @Test
    public void testGetMaxpd4() {
        int arr[] = {-2,11,-4,13,-5,-2};//作业测试用例
        assertEquals(20,new getMaxpd().getMaxpd4(arr));
    }

}

(2)测试截图

技术分享图片


四、总结

a.算法的逐步优化应该是每一个程序员不断探索的。
b.学会将项目或代码上传到coding中,用于以后的学习、阅读。
c.测试部分应该全面,实现全面覆盖,对于软件开发和维护有很大价值。


此处为 coding链接









以上是关于软件工程第三次作业的主要内容,如果未能解决你的问题,请参考以下文章

软件测试第三次作业

2017秋-软件工程第三次作业-第三周例行总结

软件概论第三次作业

软件工程第三次作业

28组第三次作业

软件工程第三次作业