zoukankan      html  css  js  c++  java
  • 软件工程第三次作业


    求子段最大和问题


    一、问题描述

    问题: 给定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)测试截图

    Test Picture


    四、总结

    a.算法的逐步优化应该是每一个程序员不断探索的。

    b.学会将项目或代码上传到coding中,用于以后的学习、阅读。

    c.测试部分应该全面,实现全面覆盖,对于软件开发和维护有很大价值。


    此处为 coding链接


  • 相关阅读:
    Sentinel Dashboard(基于1.8.1)流控规则持久化到Nacos——涉及部分Sentinel Dashboard源码改造
    测试平台MeterSphere源码入门
    Java:利用BigDecimal类巧妙处理Double类型精度丢失
    SpringBoot整合任务调度框架Quartz及持久化配置
    任务调度框架Quartz快速入门!
    Kafka超详细学习笔记【概念理解,安装配置】
    Windows环境下Zookeeper安装配置
    SpringData JPA利用Specification多条件查询
    SpringBoot事件监听机制及观察者模式/发布订阅模式
    详解Java中的IO输入输出流!
  • 原文地址:https://www.cnblogs.com/yichaoShare/p/8679115.html
Copyright © 2011-2022 走看看