伙伴链接:http://www.cnblogs.com/chengqiqin07/
一、设计思想
本实验要求输入一个正负数混合的整型数组,长度不限,在此数组的所有子数组中找到和最大的数组,并求出相应数组的和,且时间复杂度为O(n)。我们在课堂上共同讨论了多种解决方案,这些将在下面可能的解决方案中展示,在听了同学的思路和老师的讲解之后, 我们最终选取了老师课堂上描述的比较简便的思路。如下:
在输入数组的环节,采用for无限循环加if判断截止,直到触发回车键为止,将数组记录到Array中,数组长度记录到length中。
判断最大值环节,从数组的第一个数开始,判断不包含当前数的之前的数的所有子数组的和中的最大值,和包含当前数的之前的数的所有子数组的和中的最大值,以及前两者最大值的比较,利用循环和max函数的组合来实现最大值的存储与更新,在这样的循环模式下,当遇到负数时,通过之前数的最大值和负数之后最大值的变化来决定是否将负数的值加在结果之中,还是只考虑负数之后的数组成的子数组的最大值。这样就实现了题目中的所有要求。
在课堂上,我们觉得老师和同学的思路很是巧妙,在完全理解的基础上,通过思路的指导使我们编写出了此次的程序。
二、出现的问题
当然,光有思路还是不够的,在编写程序以及调试的时候也出现了些许的问题。
比如在输入数组时,刚开始的时候我们选择了用函数getchar()来输入,结果发现因为char类型和int类型的转换问题,使得输出的是ASC码,于是我们直接输入到了数组中,解决了这个问题。
还有在计算子数组最大值的时候,在最大值替换的过程中忽略了保存之前数组的最大值,导致输出结果不符合要求,在我们在纸上单步演算的过程中发现了这个问题,调整了保存最大值的顺序,最终调试成功。
三、可能的解决方案
在我们的讨论过程中,一共产生了三种解决方案:
1.在不考虑O(n)的时间复杂度的情况下,计算数组中所有子数组的和,将其存入数组中逐个进行比较,找出最大的和。
2.先单个考虑,找出整个数组的最大值,然后再两两相邻考虑,在三个相邻考虑,直到遍历完整个数组,找出最大子数组的和。
3.第三种方案就是老师课上说的那种,从数组的第一个数开始,判断不包含当前数的之前的数的所有子数组的和中的最大值,和包含当前数的之前的数的所有子数组的和中的最大值,以及前两者最大值的比较。
四、源代码
//2016 3.21 Cheng Qiqin Hao Ying //返回一个整数数组中最大子数组的和 #include<iostream> using namespace std; int main() { int Array[100]; int i,length=0;//用来记录数组长 int sumOfArray;//sumOfArray用于存放包含目前数的子数组的和的最大值 int sum=0;//sum用来存放不包含当前数的所有子数组的和的最大值 for(length=0;;) { cin>>Array[length]; length++; if(getchar()==' ') { break; } } cout<<"这个数组的长度为:"<<length<<endl; sumOfArray=Array[0]; for(i=1;i<length;i++) { sum=max(sum,sumOfArray); sumOfArray=max(sumOfArray+Array[i],Array[i]); } sumOfArray=max(sum,sumOfArray);//sumOfArray用于存放所有子数组的和的最大值 cout<<"这个整数数组的子数组之和的最大值为"<<sumOfArray<<endl; return 0; }
五、结果截图
六、总结
通过这次的实验,使我学到了一些关于求数组中子数组最大值的知识,方法虽然在书写上看似简便,实际上思路确实理解上有一定的困难。
这次的实验思路虽然不是我们自发想出来的,而是老师在课堂上对我们的启发以及提示借鉴来的,但是我们在编写时是完全理解消化之后得到的,其中的核心思想:从数组的第一个数开始,判断不包含当前数的之前的数的所有子数组的和中的最大值,和包含当前数的之前的数的所有子数组的和中的最大值,以及前两者最大值的比较,利用循环和max函数的组合来实现最大值的存储与更新,在这样的循环模式下,当遇到负数时,通过之前数的最大值和负数之后最大值的变化来决定是否将负数的值加在结果之中,还是只考虑负数之后的数组成的子数组的最大值。
还有就是学会了max函数的运用,我觉得这次实验锻炼了我们的逻辑思维能力,我想它会对我以后程序的编写起到作用的,我会将其转化为我自己的知识学以致用的!
七、工作照