最大连续子数组和求解问题
题目:最大连续子数组和求解问题
一.背景:
问题: 给定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。
--引用自《百度百科》
二.解题
方法一:暴力解法
看到题目瞬间想到大一初次接触数组时,求解数组和最大问题。但当时我就是采用将全部和算出来再进行比较的方法。
所以这次我也将采用暴力解法,直接算出所有的子数组的和,然后在所有数组和中挑选最大的进行输出。
[代码地址] ( https://git.dev.tencent.com/dtid_85494e5bcaedfaa6/zuidazishuzuqiuhe.git )
流程图如下:
代码如下:
/*
问题: 给定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。
*//*
问题: 给定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。
*/#include <stdio.h>
#include<stdlib.h>int MMax(int arr[], int N)
{int i = 0, j = 0, k = 0, sum = 0,max=0;for (i = 0; i < N; i++){for (j = i; j < N; j++){for (k = i; k <= j; k++){sum = sum + arr[k];}if (sum > max){max = sum;}sum = 0;}}return max;
}
int main()
{int *arr;int N = 0, input=0, i=0;int Max = 0;scanf_s("%d", &N);arr = (int*)malloc(sizeof(int)*N);int minus = 0;if (N < 0){printf("ERROR");return 0;}//对数组进行赋初值,并且记录负数个数for (i = 0; i < N; i++){scanf_s("%d", &input);arr[i] = input;if (input < 0){minus++;}}//如果全为负数,直接输出0,并结束程序if (minus == N){printf("0");return 0;}//对最大子数组进行求解并输出Max = MMax(arr, N);printf("%d", Max);return 0;}
下面进行代码测试环节:我选择判定/条件覆盖
测试样例 | 测试结果 | 说明 |
---|---|---|
n=6,arr[6]={-2,11,-4,13,-5,-2} | 20 | 正常情况最大子段和为20 |
n=5, arr[5] = { -1,2,3,-6,7 } | 7 | 结果为最大的一个正数 |
n=6, arr[6]={-2,-11,-4,-13,-5,-2} | 0 | 数组中都是负数,所以为0 |
n=6, arr[6]={1,2,3,4,5,6} | 21 | 结果中都是正数,结果为正数全部相加 |
测试代码如下:
#include "stdafx.h"
#include "CppUnitTest.h"
#include "..\Max\标头.h"using namespace Microsoft::VisualStudio::CppUnitTestFramework;namespace UnitTest1
{ TEST_CLASS(UnitTest1){public:TEST_METHOD(TestMethod1){int arr[6] = { -2,11,-4,13,-5,-2 }, max;max = Max(arr, 6);Assert::AreEqual(max, 20);}TEST_METHOD(TestMethod2){int arr[5] = { -1,2,3,-6,7 }, max;max = Max(arr, 5);Assert::AreEqual(max, 7);}TEST_METHOD(TestMethod3){int arr[6] = { -2,-11,-4,-13,-5,-2 }, max;max = Max(arr, 6);Assert::AreEqual(max, 0);}TEST_METHOD(TestMethod4){int arr[6] = { 1,2,3,4,5,6 }, max;max = Max(arr, 6);Assert::AreEqual(max, 21);}};
}
测试结果如下:
方法二:不太暴力的解法
身为计算机的学生,理应多多思考好的算法。且第一种方法在数据量较大时,所需时间较长。
所以我在同学的点拨下又找到一种方法。
代码如下:
#include <stdio.h>
#include <stdlib.h>int main()
{int *arr;int N = 0, input=0, i=0;int sum = 0, max = 0;scanf_s("%d", &N);arr = (int*)malloc(sizeof(int)*N);int minus = 0;//对数组进行赋初值,并且记录负数个数for (i = 0; i < N; i++){scanf_s("%d", &input);arr[i] = input;if (input < 0){minus++;}}//如果全为负数,直接输出0,并结束程序if (minus == N){printf("0");return 0;}//对最大子数组进行求解max=arr[1];for(i=0;i<N;i++){sum=sum+arr[i];if (sum>max){max=sum;}if (sum <0){sum=0;}}printf("%d",max);return 0;}
下面进行代码测试环节:我选择判定/条件覆盖
测试样例 | 测试结果 | 说明 |
---|---|---|
n=6,arr[6]={-2,11,-4,13,-5,-2} | 20 | 正常情况最大子段和为20 |
n=5, arr[5] = { -1,2,3,-6,7 } | 7 | 结果为最大的一个正数 |
n=6, arr[6]={-2,-11,-4,-13,-5,-2} | 0 | 数组中都是负数,所以为0 |
n=6, arr[6]={1,2,3,4,5,6} | 21 | 结果中都是正数,结果为正数全部相加 |
测试代码如下:
#include "stdafx.h"
#include "CppUnitTest.h"
#include "..\Max\标头.h"using namespace Microsoft::VisualStudio::CppUnitTestFramework;namespace UnitTest1
{ TEST_CLASS(UnitTest1){public:TEST_METHOD(TestMethod1){int arr[6] = { -2,11,-4,13,-5,-2 }, max;max = Max(arr, 6);Assert::AreEqual(max, 20);}TEST_METHOD(TestMethod2){int arr[5] = { -1,2,3,-6,7 }, max;max = Max(arr, 5);Assert::AreEqual(max, 7);}TEST_METHOD(TestMethod3){int arr[6] = { -2,-11,-4,-13,-5,-2 }, max;max = Max(arr, 6);Assert::AreEqual(max, 0);}TEST_METHOD(TestMethod4){int arr[6] = { 1,2,3,4,5,6 }, max;max = Max(arr, 6);Assert::AreEqual(max, 21);}};
}
测试结果如下:
总结:
通过本次实验,我仔细研究明白了子数组最大和的求法。而且深入的了解判定/条件的测试方法并进行了大量练习。通过这次实验,我已经可以熟练进行代码测试,对测试的思想以及测试工具都有了更深一步的掌握。我会在日后学习中大量练习这种测试方法,为我日后的工作学习做好准备。
转载于:https://www.cnblogs.com/FangXu1998/p/10723348.html
最大连续子数组和求解问题相关推荐
- 最大连续子数组和与JUnit测试
[题目]最大连续子数组和(最大子段和) 背景 问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],-,a[n],求该序列如a[i]+a[i+1]+-+a[j]的子段和的最大值.当 ...
- lintcode循环数组之连续子数组求和
v 题目:连续子数组求和 II 给定一个整数循环数组(头尾相接),请找出一个连续的子数组,使得该子数组的和最大.输出答案时,请分别返回第一个数字和最后一个数字的值.如果多个答案,请返回其中任意一个. ...
- php取数组中连续数,PHP实现求连续子数组最大和问题2种解决方法
本文实例讲述了PHP实现求连续子数组最大和问题2种解决方法.分享给大家供大家参考,具体如下: 问题描述 求子数组的最大和 题目描述: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整 ...
- 【剑指offer-Java版】31连续子数组的最大和
连续子数组最大和,要求O(n)时间复杂度 思路:核心思想就是当前遍历数组的时候,遇到的是一个正数,计算这个正数加上已有的和得到一个新的和 如果这个新的和比当前的正数大,那么保留该和否者更新和为当前正数 ...
- Leetcode 剑指 Offer 42. 连续子数组的最大和 (每日一题 20211014)
输入一个整型数组,数组中的一个或连续多个整数组成一个子数组.求所有子数组的和的最大值.要求时间复杂度为O(n).示例1:输入: nums = [-2,1,-3,4,-1,2,1,-5,4] 输出: 6 ...
- Algorithm:C++语言实现之求最大连续子数组(暴力法、分治法、分析法、动态规划法)
Algorithm:C++语言实现之求最大连续子数组(暴力法.分治法.分析法.动态规划法) 目录 求最大连续子数组 T1.code暴力法 O(n3) T2.分治法 O( n*log(n) ) T ...
- 算法--三种方法求连续子数组的最大和
这是一道考的烂的不能再烂的题目,但是依然有很多公司乐于将这样的题目作为笔试或面试题,足见其经典. 题目描述: 输入一个整形数组,数组里有正数也有负数. 数组中连续的一个或多个整数组成一个子数组,每个子 ...
- 连续子数组的最大和python_连续子数组的最大和
题目:输入一个整型数组,数组里有正数也有负数.数组中一个或连续的多个整数组成一个子数组.求元素和值最大的那个子数组的和值. C#实现:public static int FindGreatestSum ...
- 《剑指offer》-- 复杂链表的复制、字符串的排列、数组中出现次数超过一半的数字、连续子数组的最大和
一.复杂链表的复制: 参考牛客网的chancy:https://www.nowcoder.com/questionTerminal/f836b2c43afc4b35ad6adc41ec941dba 1 ...
最新文章
- Android怎么访问私有数据(5)
- linux文件统计命令,linux文件统计命令和目录统计命令
- 轻松掌握Ajax.net系列教程二:部署Ajax Control Toolkit
- html仿百度页面代码_百度优化需要注意的4点
- 网抑云熬夜打卡源码+微信登录+免签支付+今日打卡统计
- 三次样条曲线拟合及Matlab/Python实现
- 标题: ZZ- Linux 系统裁减指南(LiPS)
- 如何区分家里的网线是超五类还是超六类的呢?
- 5分钟学会五笔 (不用背口诀)
- strcmp函数的实现方式
- 医疗物联网的定义的业务场景
- typecho图片插件_Typecho图片表情插件Smilies1.1.3更新
- .NET Core 如何验证信用卡卡号
- Windows上查看MTU值和修改MTU的方法
- 关于Palantir—第四部分:Palantir应用程序
- GoLand Jetbrain工具使用
- 组合用计算机怎么按,一种常用的计算机键盘按键组合(快捷键)-Windows组合键,解释非常详细...
- 大学选修课计算机心得,大学选修课心得体会范文五篇
- 智能合约安全测试指南
- android 中shape的使用