结对项目——最大联通子数组

返回整数数组的最大联通子数组

一、程序要求

      1、输入一个二维整形数组,数组中有正数也有负数。

  2、求所有子数组的和的最大值,要求时间复杂度为O(n)。

  3、程序要使用的数组放在一个叫input.txt的文件中,文件格式是:

    数组的行数,                                                                                                    

    数组的列数,                                                                    

    每一行的元素,(用逗号分开)                                                            

    

  4、每一个数字都是有符号32位整数,当然,行数和列数都是正整数。

二、程序设计思想

    将二维矩阵转换成图的形式,即相邻两个数之间是联通的,记长度为1;根据图的遍历,将整个图从每个点都开始遍历一遍,便利时,当和小于0时断开两点间的路,当和大于最大和时最大和更新,这样,取以每个点为起点遍历的和的最大值即时最大联通子数组的和。遍历时,选取已遍历的联通子数组周围最大值遍历。

三、源程序

//李俏、张莹荧,2016.4.2
//求整数数组的最大子数组的和


#include<iostream> #include<fstream> #include<ctime> using namespace std; #define N 100 typedef struct { int dian[N]; int xian[N][N]; int diannum;//数组中元素个数 }Tu;// void set(Tu &shuzu,int x,int y) { int i,j; fstream infile("input.txt",ios::in); //打开指定文件 if(!infile) { cout<<"open error!"<<endl; exit(1); } infile>>x>>y; //从文件中读取数组行数和列数 shuzu.diannum=x*y; for(i=1;i<=shuzu.diannum;i++)//从文件中读取数组元素 { infile>>shuzu.dian[i]; } infile.close(); for(i=1;i<=shuzu.diannum;i+=y) { for(j=i;j<=i+y-2;j++) { shuzu.xian[j][j+1]=1; shuzu.xian[j+1][j]=1; } } for(i=1+y;i<shuzu.diannum;i+=y) { for(j=i;j<=i+x-1;j++) { shuzu.xian[j][j-y]=1; shuzu.xian[j-y][j]=1; } }//将一维数组转换成二维图的形式 } void output(Tu shuzu)//以图的形式输出数组 { for(int i=1;i<=shuzu.diannum;i++) { cout<<shuzu.dian[i]; if(shuzu.xian[i][i+1]==1) cout<<" "; else cout<<endl; } } void bianli(Tu &shuzu,int v,int visit[],int &b,int &max,int x)//遍历图 { visit[v]=1; max+=shuzu.dian[v]; if(max>=b) b=max; int a=0,bo=0; for(int w=1;w<=shuzu.diannum;w++) { for(int c=1;c<=shuzu.diannum;c++) { if((visit[w]==0)&&(shuzu.xian[c][w]==1)&&(visit[c]==1)) { a=w; bo=1; break; } } if(bo==1) { break; } } for(int w=1;w<=shuzu.diannum;w++) { for(int c=1;c<=shuzu.diannum;c++) { if((visit[w]==0)&&(shuzu.xian[c][w]==1)&&(visit[c]==1)) { if(shuzu.dian[a]<shuzu.dian[w]) { a=w; } } } } if(b+shuzu.dian[a]<0) { shuzu.xian[v][a]=0; } else { bianli(shuzu,a,visit,b,max,x); } } int NoVisit(int visit[],Tu shuzu) { int k=0,i; for(i=1;i<=shuzu.diannum;i++) { if(visit[i]==0) { k=i; break; } } return k; }//判断图中没有visit的项 int main() { Tu shuzu; int x,y; int i; fstream infile("input.txt",ios::in); //打开指定文件 if(!infile) { cout<<"open error!"<<endl; exit(1); } infile>>x>>y; //从文件中读取数组行数和列数 for(i=1;i<=x*y;i++) { infile>>shuzu.dian[i]; } infile.close(); set(shuzu,x,y); cout<<"数组为:"<<endl; output(shuzu); int v=1,b[N]={0},h=0; for(i=1;i<=shuzu.diannum;i++) { if(shuzu.dian[i]<0) { b[i]=shuzu.dian[i]; } else { int visit[N]={0}; int max=0; bianli(shuzu,i,visit,b[i],max,x); } } int max=b[1]; for(int i=2;i<=shuzu.diannum;i++) { if(b[i]>max) max=b[i]; } cout<<"最大联通子数组的和为:"<<max<<endl; return 0; }

 四、结果截图

五、心得体会

    刚开始,没有思路。老师上课时给了一个思路,但是由于自己的能力不足,未能实现。说到联通就想到了图的知识,经过翻书和查资料要把数组转化为图,再求。实现起来很是吃力,通过同学的帮助,得到了上面程序。通过本次实验,我认识到自己的能力严重不足,要加强练习,努力提高。

六、时间记录表:

学生:   李 俏                         日期 :2016年4月6日 

教师:   王建民                        课程 :软件工程      

日期

开始时间

结束时间

中断时间

净时间

活动

备注

 3.31

16:30

17:00

30

编写程序 

作业 

 4.1

14:10

15:50

30

60

编写程序

作业

 4.4

15:30

18:20

20

180

编写程序

作业

 4.5

14:20

15:30

10 

60

编写程序

 作业

 4.6

12:30

 13:30

 无

60

编写程序

 作业

 

 

 

 

 

 

 

 

 

七、缺陷记录日志:

学生        李俏,张莹荧    

日期       2016年4月6日   

教员          王建民       

程序号     4   

日期  编号 类型 引入阶段 排除阶段 修复时间 修复缺陷
 4.4  1 数组 设计 编译 15min  
描述:数组长度不合适,导致元素缺失
 4.6  2 文件 设计 编译 30min  
描述:没有考虑好,把问题想复杂了,不能有效地从文件中读出数据

 

 

 

 

 

 

 

 

 

 

 

八、工作照片

小伙伴:张莹荧(http://www.cnblogs.com/zhyying/)

 

posted @ 2016-04-06 15:11  灯下等花开  阅读(226)  评论(1编辑  收藏  举报