数组切割
个人信息:就读于燕大本科软件project专业 眼下大三;
本人博客: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
数组切割
个人信息:就读于燕大本科软件project专业 眼下大三;
本人博客: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