设计思路
首先利用rand()函数随机产生一个一维数组,数组长度通过宏定义来控制。求首尾连接的一维数组的最大子数组的和我的思路是:循环N次(N是数组的长度)依次检测数组的最大子数组的和再比较大小,保留最大值。例如长度为5的数组a[0],a[1],a[2],a[3],a[4],第一轮循环从a[0]到a[4],循环内部求出该数组的最大子数组;第二轮循环从a[1]到a[0],求出此时的最大子数组的和与第一轮的最大值比较,保留大者。依次循环N次最后就可以返回循环数组中最大子数组的和。最后把结果合理的打印出来即可(要注意负数的打印方法)。
源程序代码
#include <iostream>
#include <cstdlib>
#include <ctime>
using namespace std;
#define NUM 20
void main()
{
int a[NUM],aa[NUM],b,c,d=0,i,j,l,k,m,t=-1000,o=-1000,x,y;
cout<<"请输入数值范围:"<<endl;
cin>>b>>c;
cout<<"生成数组为:"<<endl;
srand(unsigned(time(0)));
for (i=0;i<NUM;i++)
{
a[i]=rand()%(c-b+1)+b;
cout<<a[i]<<" ";
}
for (l=0;l<NUM;l++)
{
for (m=0;m<NUM;m++)
{
if (m+l<NUM)
{
aa[m]=a[l+m];
}
else
aa[m]=a[l+m-NUM];
}
for (i=0;i<NUM;i++)
{
for (j=i;j<NUM;j++)
{
d=0;
for (k=i;k<=j;k++)
{
d=d+aa[k];
}
if (d>t) {t=d;x=l+i;y=l+j;}
}
if (t>o) o=t;
}
}
cout<<endl<<"最大子数组的和:"<<endl;
if (y<NUM)
{
for (i=x;i<=y;i++)
{
if (a[i]>=0)
{
cout<<a[i];
}
else cout<<"("<<a[i]<<")";
if (i!=y) cout<<"+";
else cout<<"=";
}
cout<<o<<endl;
}
else
{
y=y-NUM;
for (i=x;i<NUM;i++)
{
if (a[i]>=0)
{
cout<<a[i];
}
else
{
cout<<"("<<a[i]<<")";
}
cout<<"+";
}
for (i=0;i<=y;i++)
{
if (a[i]>=0)
{
cout<<a[i];
}
else
{
cout<<"("<<a[i]<<")";
}
if (i!=y)
{
cout<<"+";
}
else
{
cout<<"=";
}
}
cout<<o<<endl;
}
}
运行结果截图
该截图显示了最大子数组跨越连接点时的情况,正确输出了最大子数组的和。
编程总结
起初看到这个题目觉得有一定难度,因为脑子里没有一个清晰的解决思路。经过一段时间的思考,我想到了用上述方法来解决这个问题,在原来编程的基础上我添加了一个循环,另外做了一些修改完成了这个题目。通过此次编程过程,我意识到了解决任何问题首先要有明确的思路,没有思路就像无头苍蝇,没有思路就不要敲键盘,在有了明确的思路后编程将变得事半功倍。另外要善于在原来的编程基础上做修改来满足新问题,这就避免了重新写一些重复的代码,减少了时间成本。