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

    最大子段和

    令f[i]为从a的某一点开始到a[i]为止最大的子段和,则有以下转移方程:

    [f_i = max(f_{i - 1} + a_i, a_i) ]

    因为只需遍历一次数组就可求出,所以复杂度为(O(n))

    package org.sequix.homework3;
    
    /**
     * 提供求最大子段和的工具类。
     *
     * @author sequix
     * @version 0.0.1
     * @since 2018/03/26
     */
    public class MaxSubArray {
    
    	/**
    	 * 返回数组的最大子段和。
    	 * f[i] 到a[i]为止最大的子段和。
    	 * f[i] = max(f[i-1]+a[i], a[i])
    	 * 
    	 * @param arr 被求数组
    	 * @return 最大子段和
    	 */
    	public static int msa(int[] arr) {
    		if (arr.length == 0) {
    			throw new IllegalArgumentException("expected a non-empty array");
    		}
    		
    		int cur = arr[0];
    		int ans = cur;
    		
    		for (int i = 1, len = arr.length; i < len; ++i) {
    			cur += arr[i];
    			if (arr[i] > cur) cur = arr[i];
    			if (cur > ans) ans = cur;
    		}
    		return ans;
    	}
    }
    

    测试

    为了方便的测试,这里另写了一个工具类TestUtils。

    在TestUtils.msa中,以另一种方式求最大子段和。其枚举所有的子段,选出最大的。此解法时间复杂度为(O(n^2)),但其正确性显而易见,所以用于对拍测试。

    package org.sequix.homework3;
    
    import java.util.Random;
    
    /**
     * 提供测试用工具函数。
     * @author squix
     * @since 2018/03/19
     */
    class TestUtils {
    	private static Random random = new Random(); 
    	
    	/**
    	 * 生成[min, max]范围内的随机数。
    	 * @param min 最小值,最小可为Integer.MIN_VALUE
    	 * @param max 最大值,最大可为Integer.MAX_VALUE
    	 * @return 生成的随机数
    	 */
    	static int randomInteger(int min, int max) {
    		long num = (long) max - min + 1;
    		long kth = (long) (random.nextDouble() * num);
    		long ret = (long) min + kth;
    		return (int) ret;
    	}
    	
    	/**
    	 * 生成随机数数组。
    	 * @param size 数组大小
    	 * @param minElement 元素最小值
    	 * @param maxElement 元素最大值
    	 * @return 生成的数组
    	 */
    	static int[] generateRandomArray(int size, int minElement, int maxElement) {
    		int[] arr = new int[size];
    		for (int i = 0; i < size; ++i)
    			arr[i] = TestUtils.randomInteger(minElement, maxElement);
    		return arr;
    	}
    	
    	/**
    	 * 返回数组的最大子段和。用于和MaxSubArry.msa()对拍。
    	 * @param arr 被求数组
    	 * @return 最大子段和
    	 */
    	static int msa(int[] arr) {
    		int length = arr.length;
    		int[] sum = new int[arr.length];
    		
    		sum[0] = arr[0];
    		for (int i = 1; i < length; ++i) {
    			sum[i] = sum[i-1] + arr[i];
    		}
    		
    		int ans = arr[0];
    		for (int left = 0; left < length; ++left) {
    			for (int right = left; right < length; ++right) {
    				int tmp = sum[right];
    				if (left > 0) tmp -= sum[left-1];
    				if (ans < tmp) ans = tmp;
    			}
    		}
    		return ans;
    	}
    }
    

    具体的测试类如下:

    package org.sequix.homework3;
    
    import static org.junit.Assert.assertEquals;
    
    import org.junit.Test;
    import org.junit.jupiter.api.RepeatedTest;
    import org.junit.platform.runner.JUnitPlatform;
    import org.junit.runner.RunWith;
    
    /**
     * MaxSubArray 的测试类。
     *
     * @author sequix
     * @version 0.0.1
     * @since 2018/03/26
     */
    @RunWith(JUnitPlatform.class)
    public class MaxSubArrayTest {
    	@Test(expected=IllegalArgumentException.class)
    	public void testEmptyArray() {
    		int[] original = new int[0];
    		MaxSubArray.msa(original);
    	}
    	
    	@Test
    	public void testGeneral() {
    		int[] original = new int[] {-2, 11, -4, 13, -5, -2};
    		int expected = TestUtils.msa(original);
    		assertEquals(expected, MaxSubArray.msa(original));
    	}
    	
    	@Test
    	public void testOnlyNegatives() {
    		int[] original = TestUtils.generateRandomArray(10000, -10000, -1);
    		int expected = TestUtils.msa(original);
    		assertEquals(expected, MaxSubArray.msa(original));
    	}
    	
    	@Test
    	public void testOnlyPositives() {
    		int[] original = TestUtils.generateRandomArray(10000, 1, 10000);
    		int expected = TestUtils.msa(original);
    		assertEquals(expected, MaxSubArray.msa(original));
    	}
    	
    	@RepeatedTest(10)
    	public void testRandom() {
    		int[] original = TestUtils.generateRandomArray(10000, -10000, 10000);
    		int expected = TestUtils.msa(original);
    		assertEquals(expected, MaxSubArray.msa(original));
    	}
    }
    

    测试效果

    测试效果

    外链

    代码:Github

  • 相关阅读:
    SSH入门常用命令
    Charles基础
    经典测试用例
    Fiddler基础教程
    增、删、改、查
    一位软件测试工程师浅谈用户体验
    用户体验测试点
    IIS测试环境搭建
    禅道Bug管理工具环境搭建
    LineageOS源码定制手机系统
  • 原文地址:https://www.cnblogs.com/sequix/p/8650477.html
Copyright © 2011-2022 走看看