数组分割

数组分割

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

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

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

编程语言:C++ ;

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

编程工具:vs2008;

制图工具:office 2010 powerpoint;

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


真言

痛的领悟,痛是有领悟的,痛的时候收获更多。

题目

数组分割:有2*n长度的整形数组,将其对半分割,分割后的两个数组的和最接近。

方案

用工具栈单向遍历(思路源于栈对二叉树分支搜索的例子)

算法设计用C++代码表示如下

// 数组分割
	void Array::Divided_Array(int * data,const unsigned int length)
	{
	// 异常输入
		if(data == NULL || length == 0 || length %2 != 0)
		{
			cout<<"异常输入 Divided_Array"<<endl;
		}

	// 正常输入
		else
		{
		// 开辟空间,选择算法辅助工具
			stack<unsigned int> S ;
			int sum_stack = 0 ;
			int min;
			unsigned int now ;
			unsigned int * result = new unsigned int[length/2];

		// 求出数组的和
			int sum_array = Sum_Array(data,length) ;
			cout<<"sum_array = "<<sum_array<<endl;
		// 核心算法
			S.push(0) ;
			sum_stack = data[0] ;
			min = sum_array/2 - sum_stack;
			now = 0;
			while( true )
			{
			
			// 进栈原则
			// 和不够大
				if(sum_stack < sum_array/2)
				{

				// 元素个数不够
					if(S.size() < length/2)
					{
					// 栈顶没有走到数组尾部
						if(now < length-1)
						{
							now++;
							S.push(now);
							sum_stack += data[now];
						}

					// 栈顶已经走到数组尾部
						else{
							if(S.empty() == false)
							{
								now = S.top();
								sum_stack -= data[S.top()];
								S.pop();
								
							}
							else break;
						}
					}

				// 元素个数已经够了,
				// 检查是否比当前组合更符合大案要求,
				// 如果是则保存一下
					else if(S.size() == length/2)
					{
						if(sum_array/2 - sum_stack < min)
						{
							min = sum_array/2 - sum_stack;
							Stack_To_Array(S,result);
						}
					// 出栈,更新栈,继续寻找
						now = S.top();
						sum_stack -= data[now];
						S.pop();

					}
				}

			// 出栈原则
				else if(sum_stack > sum_array/2)
				{
				// 出栈,更新栈,继续寻找
					now = S.top();
					sum_stack -= data[now];
					S.pop();
					
				}

			// 如果当前栈的和等于数组和的一半
				else
				{
					if(S.size() == length/2)
					{
						min = sum_array/2-sum_stack;
						Stack_To_Array(S,result);
						break;
					}
					else 
					{
						// 出栈,更新栈,继续寻找
						if(S.empty() == false)
						{
							now = S.top();
							sum_stack -= data[S.top()];
							S.pop();						
						}
						else break;
					}
				}
			}

			cout<<"min = "<<min<<endl;
			cout<<"sum_stack = "<<sum_stack<<endl;
			cout<<"answer for 数组分割"<<endl;
			for(unsigned int i=0;i<length/2;i++)
			{
				cout<<data[result[i]]<<" ";
			}
			cout<<endl;
			
		}
	}

// 数组求和
	int Array::Sum_Array(int * data,const unsigned int length)
	{
	// 异常输入
		if(data == NULL || length == 0 || length %2 != 0)
		{
			cout<<"异常输入 Divided_Array"<<endl;
			return -1;
		}

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



// 栈复制到数组
	void Array::Stack_To_Array(stack<unsigned int> S,unsigned int * &data)
	{
		unsigned int length = S.size();
		if(length == 0)
		{
			return void(0);
		}
		data = new unsigned int[length];
		for(unsigned int i = length-1;i < length;i--)
		{
			data[i] = S.top();
			S.pop();
		}
		return void(0);
	}


实验

数组 int data[]={-9,0,-3,-5,-1,-2,6,80,56,23};

程序结果

这里只输出了一个分割后的数组 -9 0 -5 6 80 ,还有一个数组是 -3 -1 -2 56 23 


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值