一.题目及要求
题目:返回一个二维整数数组中最大子数组的和。
要求: 输入一个二维整形数组,数组里有正数也有负数。
二维数组首尾相接,象个一条首尾相接带子一样。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
二.设计思路
(1)二维数组我们采用的还是数组的形式;
(2)读取nxm的二维数组,储存成nx2m,把前m列重复加在二维数组的最后;
(3)搜索最大数组的方法和不循环的二维数组是一样的,就是再加上判断条件加以限制。
三、源代码
1 // 二维数组循环.cpp : Defines the entry point for the console application. 2 // 3 4 #include "stdafx.h" 5 #include "fstream.h" 6 #include "iostream.h" 7 #define MAXSIZE 50 8 9 //*****读取数组信息***** 10 void ReadArr(int arr[][MAXSIZE],int &len1,int &len2) 11 { 12 ifstream infile("Arr.txt"); 13 if(!infile) 14 cout<<"读取失败!"<<endl; 15 else 16 { 17 infile>>len1>>len2; 18 for(int i=0;i<len1;i++) 19 { 20 for(int j=0;j<len2;j++) 21 { 22 infile>>arr[i][j]; //从文件中读取数据 23 arr[i][j+len2]=arr[i][j]; 24 } 25 } 26 } 27 28 } 29 //*****显示矩阵***** 30 void ShowArr(int arr[][MAXSIZE],int len1,int len2,int size1,int size2) 31 { 32 for(int i=len1;i<=size1;i++) //将文件中的数组输出 33 { 34 for(int j=len2;j<=size2;j++) 35 { 36 cout<<arr[i][j]<<"\t"; 37 } 38 cout<<endl; 39 } 40 } 41 //*****求和公式***** 42 int GetSum(int arr[][MAXSIZE],int len1,int len2,int size1,int size2) 43 { 44 int sum=0; 45 for(int i=len1;i<=size1;i++) //求任意数组中两个数之间的数的和 46 { 47 for(int j=len2;j<=size2;j++) 48 { 49 sum+=arr[i][j]; 50 } 51 } 52 return sum; 53 } 54 55 int main(int argc, char* argv[]) 56 { 57 int len1,len2,max,sum; //len1是行数,len2是列数 58 int line1,line2,row1,row2; //和最大的矩阵的两个坐标 59 int arr[MAXSIZE][MAXSIZE]; 60 ReadArr(arr,len1,len2); 61 cout<<"矩阵:"<<endl; 62 ShowArr(arr,0,0,len1-1,len2-1); 63 cout<<endl; 64 line1=0; 65 line2=0; 66 row1=0; 67 row2=0; 68 sum=0; 69 max=arr[0][0]; 70 for(int i=0;i<len1;i++) //第一个数的行数 71 { 72 for(int j=0;j<len2;j++) //第一个数的列数 73 { 74 for(int m=i;m<len1;m++) //第二个数的行数 75 { 76 for(int n=j;(n<2*len2)&&(n<j+3);n++) 77 { //第二个数的列数 78 sum=GetSum(arr,i,j,m,n); //求出这两个数构成的矩阵的和 79 if(sum>max) 80 { 81 max=sum; 82 line1=i; //保存第一个数的行 83 line2=m; //保存第二个数的行 84 row1=j; //保存第一个数的列 85 row2=n; //保存第二个数的列 86 } 87 } 88 } 89 } 90 } 91 cout<<"和最大的子矩阵:"<<endl; 92 ShowArr(arr,line1,row1,line2,row2); 93 cout<<"最大的和:"<<max<<endl; 94 return 0; 95 }
四、运行截图
五、心得体会
这次的拓展我们很快就实现了,是因为写二维数组的时候,我们的思路比较清晰,函数功能比较专一规范,所以在拓展的时候比较容易。思路上我们采用了上次一维循环数组别的同学的想法,就是在每行数组的末尾再写一遍该行数据,遍历时加上长度的限制条件就可以了。
这次的拓展和上次的形成了较强的对比,还是好的算法清晰的思路比较好。因为上次我们的一维数组算法写的不太好,所以导致我们在后面的拓展中不得不重写。
六、无图无真相