第四章 最大子数组问题(股票最大收益) C++实现 算法导论

最简单的方法就是暴力破解法,即尝试每一对可能买入卖出的日期组合,只要卖出日期在买入日期之后就行,这种运行时间n的平方量级。
最大子数组问题可以归为分治算法。只不过这个和平常的分治算法问题不同,这个问题的解分为三部分:最大值可能完全位于最左边,也可能完全位于最右边,也有可能跨越了中点。因此这个问题的关键点是求出位于中间的最大值  。然后返回max(leftsum,centrlsum,rightsum)。代码如下:

函数说明:Diffivec函数是为了求得相邻两天的差值,求值后,ivec[0]将不再使用,差值位于1到length-1;

运行中输入的数字为:连续的N天的股票价格,而结果就是一次买入,一次卖出的最大收益。  我完全按照书中的输入,得出的结果在最后图上所示。

#include 
#include 

using namespace std;

static const int Maxnum = 1024;     //最大输入个数

int Maxcentrl(vector &ivec,int left,int mid,int right)    //求跨越中间点的最大值
{
	int maxleftsum,leftsum,maxrightsum,rightsum;
	maxleftsum = leftsum = maxrightsum = rightsum = 0;
	for(int i = mid;i >=left;--i)
	{
		leftsum += ivec[i];
		if(leftsum > maxleftsum)
			maxleftsum = leftsum;
	}
	for(int i = mid + 1;i <= right;++i)
	{
		rightsum += ivec[i];
		if(rightsum > maxrightsum)
			maxrightsum = rightsum;
	}
	return (maxleftsum + maxrightsum);
}
int max(int left,int centrl,int right)
{
	if(left < centrl)
	{
		if(centrl < right)
			return right;
		else
			return centrl;
	}else if(left < right)
		return right;
	else
		return left;
}

int MaxSub(vector &ivec,int left,int right)
{
	int leftmax,rightmax,centrlmax;
	int mid;
	if(left == right)			//基准情况
	{
		if(ivec[left] > 0)		//要考虑小于零的情况哦
			return ivec[left];
		else
			return 0;
	}else
	{
		mid = (left + right) / 2;
	}
	leftmax = MaxSub(ivec,left,mid);	//递归求左最大值
	rightmax = MaxSub(ivec,mid + 1,right);	//递归求右最大值
	centrlmax = Maxcentrl(ivec,left,mid,right);	//求跨越中间点的最大值	
	return max(leftmax,centrlmax,rightmax);		//返回三者中的最大值

}

void Diffivec(vector &ivec,int length) 	//这个函数的目的是求得股票的差值
{
	for(int i = length - 1;i >= 0;--i)
	{
		ivec[i] = ivec[i] - ivec[i - 1];
	}
}

int main(void)
{
	vector ivec;
	int elements;
	int length = 0;
	while(length < Maxnum && cin >> elements)
	{
		ivec.push_back(elements);
		++length;
	}
	cout << "the original data is " << endl;
	for(int i = 0;i < length;i++)
	{
		cout << ivec[i] << ((i + 1) % length ? ' ':'\n');
	}

	Diffivec(ivec,length);
	cout << "the Diff data is " << endl;
	for(int i = 1;i < length;i++)
	{
		cout << ivec[i] << ((i + 1) % length ? ' ':'\n');
	}
	
	int maxsubsum;
	maxsubsum = MaxSub(ivec,1,length - 1);

	cout << " test max function " << max(0,1,2) << endl;
	
	cout << " the maxsub is " << maxsubsum << endl;	
	return 0;
}

第四章 最大子数组问题(股票最大收益) C++实现 算法导论_第1张图片



如有问题,欢迎交流哦。

你可能感兴趣的:(算法导论)