求二维数组中子数组和中最大的值,及子数组

求二维数组中子数组和中最大的值,及子数组

个人信息:就读于燕大本科软件工程专业 目前大三;

本人博客:google搜索“cqs_2012”即可;

个人爱好:酷爱数据结构和算法,希望将来从事算法工作为人民作出自己的贡献;

编程语言:C++ ;

编程坏境:Windows 7 专业版 x64;

编程工具:vs2008;

制图工具:office 2010 powerpoint;

硬件信息:7G-3 笔记本;

真言

每次着急写程序,碰到问题就头疼,头疼之后便是满满的收获,付出总有回报。

题目

求二维数组中子数组和中最大的值,及子数组

方案

我们已经做过一维数组的问题。如果你没有看过一维数组的问题,请戳  求子数组之和最大值

二维数组是一维数组的数组,这样理解起来,我们就不费事了

我的算法是先将压缩列,即每一列的和作为新数组的元素来组成新的数组来简化问题,然后就变成一维数组求最大子数组问题了

具体算法设计用C++表示如下

// 求出二维数组的最大子二维数组
	int Array::Max_Sum_Sub_Double_Array(int **data,const unsigned int row,const unsigned int column)
	{
	// 异常输入
		if(data == NULL || row == 0 || column == 0)
		{
			cout<<"异常输入 Max_Max_Sub_Double_Array"<<endl;
			return -1;
		}

	// 正常输入
		else
		{
		// 核心算法数据初始化
		// 按照一位数组来处理列,把每一列作为一个数
			int * OneArray = new int[column];
			for( unsigned int i=1;i <= column;i++ )
			{
				OneArray[i-1] = Sum_Sub_Column_Double_Array(data,row,column,i,1,row);
			}
			unsigned int L,R;
			Border_Max_Sum_Sub_Array(OneArray,column,L,R);
			delete [] OneArray;

		// 按照一位数组来处理行,把每一行作为一个数
			OneArray = new int[row];
			for(unsigned int i=1;i <= row;i++)
			{
				OneArray[i-1] = Sum_Sub_Row_Double_Array(data,row,column,i,L,R);
			}
			unsigned int U,D;
			Border_Max_Sum_Sub_Array(OneArray,row,U,D);
			cout<<U<<" "<<D<<" "<<L<<" "<<R<<endl;
			return Max_Sum_Sub_Array(OneArray,row); 	
		}
	}
	

// 求出二维数组中的某一列的子数组的和
	int Array::Sum_Sub_Column_Double_Array(int ** data,const unsigned int row,const unsigned int column,unsigned int mycolumn,unsigned int s,unsigned int e)
	{
	// 异常输入
		if(data == NULL || row == 0 || column == 0 || mycolumn > column || s>e || e>row)
		{
			cout<<"异常输入 Sum_Sub_Column_Double_Array"<<endl;
			return -1;
		}

	// 正常输入
		else
		{
			int sum = 0;
			for(unsigned int i = s;i <= e;i++)
			{
				sum += data[i-1][mycolumn-1];
			}
			return sum;
		}
	}


// 求出二维数组中的某一行的子数组的和
	int Array::Sum_Sub_Row_Double_Array(int **data,const unsigned int row,const unsigned int column,unsigned int myrow,unsigned int s,unsigned int e)
	{
	// 异常输入
		if(data == NULL || row == 0 || column == 0 || myrow > row || s>e || e> column)
		{
			cout<<"异常输入 Sum_Sub_Row_Double_Array"<<endl;
		}

	// 正常输入
		else{
			int sum = 0;
			for(unsigned int i=s;i <= e;i++)
			{
				sum += data[myrow-1][i-1];
			}
			return sum;
		}
	}



// 求数组的子数组之和最大的边界
	void Array::Border_Max_Sum_Sub_Array(int *data,unsigned int const length,unsigned int & L,unsigned int & R)
	{
	// 异常输入
		if(data == NULL || length == 0 )
		{
			cout<<"异常输入 Border_Max_Sum_Sub_Array"<<endl;
			return void(0);
		}

	// 正常输入
		else
		{
			bool all_fushu = true ;
			unsigned int max = 0;

		// 检查是否所有的数是否都是负数,并记录最大值的下表
			for( unsigned int i = 0;i < length;i++ )
			{
				if( data[i] >= 0 )
				{
					all_fushu = false ;
					break ;
				}
				else if( data[i] > data[max] )
				{
					max = i ;
				}
			}

		// 如果都是负数
			if(all_fushu == true)
			{
				R = L = max+1;
				return void(0);
			}

			// 如果不都是负数
			else
			{
			// 核心算法 初始化
				int left_sum = data[0],right_sum = data[length-1] ;
				int left = 0,right =length-1;
				L = left; R = right ;

			// 选择前进方向
				while(left < right-1)
				{
					if(left_sum < right_sum)
					{
						if(left_sum < 0)
						{
							left_sum = 0 ;
							L = left+1 ;
						}
						left++;
						left_sum += data[left];
					}
					else
					{
						if(right_sum < 0)
						{
							right_sum = 0;
							R = right -1;
						}
						right--;
						right_sum += data[right];
					}
				}

			// 寻求结果

			// 如果舍弃左半个数组,保留右半个数组
				if(left_sum <= 0)
				{
					L = right + 1;
					R++ ;
				}

			// 如果舍弃右半个数组,保留左半个数组
				else if(right_sum <= 0){
					L++;
					R = left+1;
				}

			// 两边都不舍弃
				else{
					L++;R++;
				}

				return void(0);
			}	
		}
	}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值