一、题目与要求
题目:返回一个二维整数数组中最大子数组的和。
要求:
输入一个二维整形数组,数组里有正数也有负数。
二维数组首尾相接,象个一条首尾相接带子一样。
数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。
求所有子数组的和的最大值。要求时间复杂度为O(n)。
二、设计思想
通过上次求解简单一维回环数组的最大子数组问题的解决,我们采取的方法并不是时间复杂度为o(n)的算法。关于实现数组回环,我们的方法仍是定义一个二倍长数组来首尾存取两次待求数组,以此解决回环。
三、源代码
1 /*====================================================================== 2 # Author: TianYongTao && ZhangYaPeng 3 # E-Mail: [email protected] 4 # Last modified: 2015-04-01 10:14 5 # Filename: Demo.cpp 6 # Description: 求二维回环数组的最大子数组 7 ======================================================================*/ 8 #include "stdafx.h" 9 # include <iostream> 10 # include <string> 11 # define MaxRow 20 12 # define MaxCol 20 13 using namespace std; 14 int Arr[MaxRow][MaxCol]; 15 int Array[MaxRow][2*MaxCol]; 16 int SumArr(int x1,int y1,int x2,int y2) //子数组求和 17 { 18 int sum=0; 19 for(int i=x1;i<x2;i++) 20 { 21 for(int j=y1;j<y2;j++) 22 { 23 sum+=Array[i][j]; 24 } 25 } 26 return sum; 27 } 28 29 void LoadFile(int Arr[][MaxCol],int & Row,int & Col) 30 { 31 FILE * infile = fopen("D:\\input.txt","r"); 32 int num[100]; 33 int count=0; 34 if(!infile) 35 { 36 cout<<"文件读取失败!"<<endl; 37 exit(-1); 38 } 39 else 40 { 41 char str[10]; 42 fscanf(infile,"%[^,]%*c",str); 43 Row = atof(str); 44 fscanf(infile,"%[^,]%*c",str); 45 Col = atof(str); 46 while(!feof(infile)) 47 { 48 fscanf(infile,"%[^,]%*c",str); 49 num[count++]=atof(str); 50 } 51 } 52 for(int i=Row-1;i>=0;i--) 53 { 54 for(int j=Col-1;j>=0;j--) 55 { 56 Arr[i][j]=num[--count]; 57 } 58 } 59 for(int i=0;i<Row;i++) 60 { 61 for(int j=0;j<Col;j++) 62 { 63 Array[i][j] = Arr[i][j]; 64 Array[i][j+Col] = Arr[i][j]; 65 } 66 } 67 } 68 69 //测试函数 70 int main() 71 { 72 int Row=0; 73 int Col=0; 74 LoadFile(Arr,Row,Col); 75 for(int i=0;i<Row;i++) 76 { 77 for(int j=0;j<Col;j++) 78 { 79 cout<<Arr[i][j]<<"\t"; 80 } 81 cout<<endl; 82 } 83 int x1,y1; //代表左上角点的横纵坐标 84 int x2,y2; //代表右上角点的横纵坐标 85 int flag1,flag2,flag3,flag4; //(flag1,flag2)标识最大子数组的左上角坐标 (flag3,flag4)标识最大子数组的右下角坐标 86 flag1=flag2=flag3=flag4=0; 87 int max = Array[0][0]; //max存储比较过程中的最大值 88 for(x1=0;x1<Row;x1++) 89 { 90 for(y1=0;y1<Col;y1++) 91 { 92 for(x2=x1+1;x2<=Row;x2++) 93 { 94 for(y2=y1+1;y2<=2*Col;y2++) 95 { 96 if((y2-y1) > Col) 97 { 98 break; 99 } 100 if(SumArr(x1,y1,x2,y2)>max) 101 { 102 max = SumArr(x1,y1,x2,y2); 103 flag1=x1; 104 flag2=y1; 105 flag3=x2; 106 flag4=y2; 107 } 108 } 109 } 110 } 111 } 112 cout<<"最大子数组为:"<<endl; 113 for(int i=flag1;i<flag3;i++) 114 { 115 for(int j=flag2;j<flag4;j++) 116 { 117 cout<<Array[i][j]<<"\t"; 118 } 119 cout<<endl; 120 } 121 cout<<"该最大子数组的和为:"<<max<<endl; 122 return 0; 123 }
四、运行结果
1.文件内容
2.运行结果
五、结果测试
1.全为正数
2.全为负数
3.有正有负
六、心得体会
该程序在实现的时候只是对上次的二维数组求最大子数组进行了小小的改动,具体实现方法没有多大的变动,唯一遗憾的是没有实现时间复杂度为o(n)。
在结组开发的过程中,我和田永涛配合的越来越默契,能在一定程度上提高开发的效率。
时间: 2024-11-03 21:32:19