您的位置:首页 > 其它

算法导论:分治策略__最大子数组问题

2015-02-09 18:17 681 查看
<a target=_blank href="http://segmentfault.com/blog/binta/1190000000733277">可以参考http://segmentfault.com/blog/binta/1190000000733277</a>
</pre><pre name="code" class="cpp">//参考书上源代码,但是对于分治法求解,返回子数组范围在一些情况下有一些问题。
</pre><pre name="code" class="cpp">// 求最大子数组  暴力法与分治法
#include <iostream>
#include <limits.h>
#include <stdio.h>
using namespace std;

// 暴力求解法
int maxsubset(int* a,int len,int& from, int& to)
{
int submax = INT_MIN;
int i,j,k;
int ncount =0;
for(i=0;i<len;i++)
for(j=i;j<len;j++)
{
int temp =0;
for(k = i;k<=j;k++)
{
temp = temp + a[k];
}
if(temp > submax)
{
submax = temp;
from = i;
to = j;
}

//          cout<<ncount++<<": "<<submax<<endl;
}
return submax;
}

//分治法
int findCross(int* a, int low, int mid,int high,int& from, int& to)
{

int leftsum = INT_MIN;
int sum =0;
for(int i = mid;i>=low;i--)
{
sum = sum +a[i];
if(sum > leftsum)
{
leftsum = sum;
from = i;
}
}

int rightsum = INT_MIN;
sum = 0;
for(int i = mid+1;i<=high;i++)
{
sum = sum +a[i];
if(sum > rightsum)
{
rightsum = sum;
to = i;
}
}

return (leftsum+rightsum);
}

int findmax(int* a,int low, int high,int& from,int& to)
{
int leftsum,rightsum,crosssum;
int mid;
int froml,tol,fromr,tor,fromc,toc;
if(high == low)
return a[low];
else
{
mid = (low+high)/2;
leftsum = findmax(a,low,mid,froml,tol);
rightsum = findmax(a,mid+1,high,fromr,tor);
crosssum = findCross(a,low,mid,high,fromc,toc);

if (leftsum >= rightsum && leftsum >=crosssum)
{
from = froml;
to = tol;
cout<<leftsum<<"  left is from:"<<from<<" to:"<<to<<endl;
return leftsum;
}
else if(rightsum >= leftsum && rightsum >= crosssum)
{
from = fromr;
to = tor;
cout<<rightsum<<"  right is from:"<<from<<" to:"<<to<<endl;
return rightsum;
}
else
{
from = fromc;
to = toc;
cout<<crosssum<<"  cross is from:"<<from<<" to:"<<to<<endl;
return crosssum;
}
}
}

int main()
{
int a[]={3,-1,2,5,-3,-14,-6,2,1,8,-3,5,9};
int b[] = {4};
int from = 0,to = 0;
cout<<findmax(a,0,sizeof(a)/sizeof(int)-1,from,to);
cout<<"is from:"<<from<<" to:"<<to<<endl;
//   cout<<findCross(a,0,(0+4)/2,4,from,to);
//   cout<<"from:"<<from<<" to:"<<to<<endl;
printf("the maxsubset:%d\n",maxsubset(a,13,from,to));
printf("from %d to %d",from ,to);
return 0;
}


编程总结:

1.
http://www.cplusplus.com/reference/climits/
C++ 中有#include <limits.h> 

中定义了各种无穷大和无穷小,在使用的时候也可以自己定义 #define INT_MAX 65535

2.

使用多个参数返回的时候,C++可以使用引用类型。

3.使用分治策略要注意最后的停止条件,这个非常关键。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: