最大子序列分治实现以及改进

来源:互联网 发布:淘宝html源代码 编辑:程序博客网 时间:2024/06/10 02:22
最大子序列,一开始我是用比较方便的向量的:
#include <string>#include <iostream>#include <vector>#include<climits>using namespace std;


vector<int> f_m_c_s(vector<int> &a,int low,int mid,int high){int left_sum=INT_MIN;int sum=0;int max_left;for(int i=mid-1;i!=low-1;--i){sum=sum+a[i];if(sum>left_sum){left_sum=sum;max_left=i;}}int right_sum=INT_MIN;sum=0;int max_right;for(int j=mid;j!=high;++j){sum=sum+a[j];if(sum>right_sum){right_sum=sum;max_right=j;}}return vector<int>{max_left,max_right,left_sum+right_sum};}vector<int> f_m_s(vector<int> a,int low,int high){if(high==low+1){return vector<int>{low,high,a[low]};}else{int mid=(low+high)/2; vector<int>a1 = f_m_s(a,low,mid); int left_low=a1[0],left_high=a1[1],left_sum=a1[2]; //cout<<"low="; //for(auto i:a1){cout<<i<<" ";} //cout<<'\n'<<endl;  vector<int>a2=f_m_s(a,mid,high); int right_low=a2[0],right_high=a2[1],right_sum=a2[2]; //cout<<"high="; //for(auto i:a2){cout<<i<<" ";} //cout<<'\n'<<endl;  vector<int>a3=f_m_c_s(a,low,mid,high); int cross_low=a3[0],cross_high=a3[1]; int cross_sum=a3[2]; //cout<<"cross="; //for(auto i:a3){cout<<i<<" ";} //cout<<'\n'<<endl;  if(left_sum>=right_sum && left_sum>=cross_sum){ return a1;} else if(right_sum>=left_sum && right_sum>=cross_sum){ return a2;} else {return a3;}}}

但是格式十分麻烦,看了网上的答案之后,发现可以定义一个类,专门用来储存三个数字。

实现:

typedef struct{unsigned left; unsigned right; unsigned sum;} ma;

这样把上面的分治方法再写一次:

ma f_m_c_s_ma(int a[], unsigned low, unsigned mid, unsigned high){ma result;int left_sum=INT_MIN;int sum=0;for(int i=mid-1;i!=low-1;--i){sum=sum+a[i];if(sum>left_sum){left_sum=sum;result.left=i;}}int right_sum=INT_MIN;sum=0;for(int j=mid;j!=high;++j){sum=sum+a[j];if(sum>right_sum){right_sum=sum;result.right=j;}}result.sum=left_sum+right_sum;return result;}ma f_m_s_ma(int a[],unsigned low,unsigned high){if(high==low+1){ma result={low,high,a[low]};return result;}else{int mid=(low+high)/2;ma left=f_m_s_ma(a,low,mid);ma right=f_m_s_ma(a,mid,high);ma cross=f_m_c_s_ma(a,low,mid,high);if(left.sum>=right.sum && left.sum>=cross.sum){return left;}else if(right.sum>=left.sum && right.sum>=cross.sum){return right;}else {return cross;}}}

理论上是没有错的