伙伴链接:http://www.cnblogs.com/haoying1994/
一、设计思想
本实验要求输入一个正负数混合的整型数组,长度不限,在此数组的所有子数组中找到和最大的数组,并求出相应数组的和,且时间复杂度为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()=='\n') { 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; }
五、结果截图
六、总结
通过这次的实验,我觉得我的逻辑思维得到了提升,并且收获了关于求数组中子数组最大值的知识,我觉得我们的源程序代码虽然看起来很短,很简单,其实关键的代码在理解上还是存在着 一定的难度的。
因为有O(n),使我们选择了老师在课堂上提示我们的,于是我们按照老师的思路编写了程序:从数组的第一个数开始,判断不包含当前数的之前的数的所有子数组的和中的最大值,和包含当前数的之前的数的所有子数组的和中的最大值,以及前两者最大值的比较,利用循环和max函数的组合来实现最大值的存储与更新,在这样的循环模式下,当遇到负数时,通过之前数的最大值和负数之后最大值的变化来决定是否将负数的值加在结果之中,还是只考虑负数之后的数组成的子数组的最大值。因此这次的思路虽然不是完全凭我们自己想出来的,但是我们对于思想的理解是深刻的,所有我们仍然收获了许多知识。
相信在今后的程序开发中,我会从今天的思路中借鉴许多思想,帮助我解决许多问题,发挥它的作用的,在后面的实验中我还是会继续努力下去的!
七、工作照