2018.9.25
前面一段时间参加了研究生数学建模大赛。比赛完又考了一个托业。感觉数学英语功底得到了很大提升,同时也断更了两周。总算在中秋节第二天正式回归了。
回归第一题看得真是感慨万分。这题是我刚刚入门数据结构与算法的时候做的第一道大题,解法至今记忆犹新。能够实现的算法有两种:
方法一:动态规划/在线处理算法,o(n)。设定一个积累值和一个结果值,从左向右不断累加,当积累值大于结果值的时候更新结果,当积累结果为负数的时候抛弃之前积累的结果。既然刚刚从数学建模大赛回来,那就摆个动态规划的模型吧。
本题的动态规划模型:
之前写过的代码:#数据结构与算法学习笔记#PTA3:在线处理算法求最大子列和,并返回最大子列和头尾元素(C/C++)(2004年浙大计科考研复试)
方法二:分治算法,o(logn)。基本思想是递归,把每一次递归看成三部分:对每个序列二分,左边子序列、右边子序列、跨中线子序列分别求最大子列和,挑选最大的子列和进行返回。递归找到最大子列和。
之前写过的代码:#数据结构与算法学习笔记#PTA4:分治算法求最大子列和(C/C++)
题目描述
HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。今天测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢?例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住?(子向量的长度至少是1)
之前两篇文章都是在3月份的时候写的,如果要说这半年来有什么成长的话,那应该是现在开始会有意识地优化代码的效率和可读性了吧。
Java实现(方法一):
/**
*
* @author ChopinXBP
* 给一个数组,返回它的最大连续子序列的和。
*
*/
public class FindGreatestSumOfSubArray_29 {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] array = {6,-3,-2,7,-15,1,2,2};
System.out.println(FindGreatestSumOfSubArray(array));
}
//动态规划/在线处理算法
public static int FindGreatestSumOfSubArray(int[] array) {
if(array == null)return 0;
if(array.length == 0)return array[0];
int max = array[0]; //积累值
int result = array[0]; //最终结果
for(int i = 1; i < array.length; i++){
max += array[i];
if(max > result) result = max; //当积累值大于结果值则更新结果
if(max < 0) max = 0; //当和为负数抛弃之前积累结果
}
return result;
}
}
C++实现(方法一):
bool g_InvalidInput = false;
int FindGreatestSumOfSubArray(int *pData, int nLength)
{
if((pData == NULL) || (nLength <= 0))
{
g_InvalidInput = true;
return 0;
}
g_InvalidInput = false;
int nCurSum = 0;
int nGreatestSum = 0x80000000;
for(int i = 0; i < nLength; ++i)
{
if(nCurSum <= 0)
nCurSum = pData[i];
else
nCurSum += pData[i];
if(nCurSum > nGreatestSum)
nGreatestSum = nCurSum;
}
return nGreatestSum;
}
测试代码:
// ====================测试代码====================
void Test(char* testName, int* pData, int nLength, int expected, bool expectedFlag)
{
if(testName != NULL)
printf("%s begins: \n", testName);
int result = FindGreatestSumOfSubArray(pData, nLength);
if(result == expected && expectedFlag == g_InvalidInput)
printf("Passed.\n");
else
printf("Failed.\n");
}
// 1, -2, 3, 10, -4, 7, 2, -5
void Test1()
{
int data[] = {1, -2, 3, 10, -4, 7, 2, -5};
Test("Test1", data, sizeof(data) / sizeof(int), 18, false);
}
// 所有数字都是负数
// -2, -8, -1, -5, -9
void Test2()
{
int data[] = {-2, -8, -1, -5, -9};
Test("Test2", data, sizeof(data) / sizeof(int), -1, false);
}
// 所有数字都是正数
// 2, 8, 1, 5, 9
void Test3()
{
int data[] = {2, 8, 1, 5, 9};
Test("Test3", data, sizeof(data) / sizeof(int), 25, false);
}
// 无效输入
void Test4()
{
Test("Test4", NULL, 0, 0, true);
}
int _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
return 0;
}
#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#