求向量的最大子向量和

编程珠玑第8章求子向量和算法的C++实现

#include "stdafx.h"
#include 
#include 
#include 
#include 
#include "windows.h"
using namespace std;

/// O(n^3)算法
template
bool MaxSubVectorSum1( InPt posBegin_, InPt posEnd_, ValueType& MaxSubSum_ )
{
	if( posBegin_ == posEnd_ )
	{
		return false;
	}

	MaxSubSum_ = 0;
	for( ; posBegin_ != posEnd_; ++posBegin_ )
	{
		for(InPt posTemp = posBegin_; posTemp != posEnd_; ++posTemp )
		{
			ValueType SubSum = 0;
			InPt posTempEnd = posTemp;
			advance(posTempEnd, 1);
			for( InPt posSum = posBegin_; posSum != posTempEnd; ++posSum )
			{
				SubSum += *posSum;
			}

			MaxSubSum_ = max(MaxSubSum_, SubSum);
		}
	}

	return true;
}

/// O(n^2)算法
template
bool MaxSubVectorSum2( InPt posBegin_, InPt posEnd_, ValueType& MaxSubSum_ )
{
	if( posBegin_ == posEnd_ )
	{
		return false;
	}

	MaxSubSum_ = 0;
	for( ; posBegin_ != posEnd_; ++posBegin_ )
	{
		ValueType SubSum = 0;
		for(InPt posTemp = posBegin_; posTemp != posEnd_; ++posTemp )
		{
			SubSum += *posTemp;
			MaxSubSum_ = max(MaxSubSum_, SubSum);
		}
	}

	return true;
}

/// O(nlogn)算法
template
bool MaxSubVectorSum3( InPt posBegin_, InPt posEnd_, ValueType& MaxSubSum_ )
{
	MaxSubSum_ = 0;

	int iDistance = distance(posBegin_, posEnd_ );
	if( iDistance <= 0 )
	{
		return false;
	}
	else if( iDistance == 1 )
	{
		MaxSubSum_ = max(MaxSubSum_, *posBegin_);
	}
	else
	{
		InPt posMiddle = posBegin_;
		advance(posMiddle, iDistance / 2);
		ValueType MaxSubMaxLeft, MaxSubMaxRight;

		/// 前半部最大和
		MaxSubVectorSum3(posBegin_, posMiddle, MaxSubMaxLeft);
		/// 后半部最大和
		MaxSubVectorSum3(posMiddle, posEnd_, MaxSubMaxRight);
		MaxSubSum_ = max( MaxSubMaxRight, MaxSubMaxLeft );

		/// 跨越中点的最大和
		ValueType MaxCrossL = 0;
		ValueType MaxCrossR = 0;
		ValueType Sum = 0;
		for( reverse_iterator pos = reverse_iterator(posMiddle) ; pos != reverse_iterator(posBegin_); ++pos )
		{
			Sum += *pos;
			MaxCrossL = max(MaxCrossL, Sum);
		}

		Sum = 0;
		for( InPt pos = posMiddle ; pos != posEnd_; ++pos )
		{
			Sum += *pos;
			MaxCrossR = max(MaxCrossR, Sum);
		}
		ValueType MaxCross = MaxCrossL + MaxCrossR;
		MaxSubSum_ = max(MaxSubSum_, MaxCross);
	}

	return true;
}


/// O(n)算法
template
bool MaxSubVectorSum4( InPt posBegin_, InPt posEnd_, ValueType& MaxSubSum_ )
{
	if( posBegin_ == posEnd_ )
	{
		return false;
	}

	/// 基于以下思想,最大的连续子向量中包含第一个元素的子向量之和绝不会小于0
	MaxSubSum_ = 0;
	ValueType MaxTemp = 0;
	for( InPt pos = posBegin_; pos != posEnd_; ++pos )
	{
		MaxTemp = max( MaxTemp + *pos, 0 );
		MaxSubSum_ = max( MaxSubSum_, MaxTemp );
	}
	return true;
}

int random( int iStart_, int iEnd_ )
{
	return iStart_ + rand()%(iEnd_ - iStart_);
}

int _tmain(int argc, _TCHAR* argv[])
{
	srand(unsigned int(time(0)));
	vector coll;
	coll.resize(1000);
	for(int i = 0; i < 1000; ++i)
	{
		coll[i] = random(-500, 500);
	}
	cout << endl;

	int MaxSubSum;
	DWORD dwStart, dwEnd;
 	
 	dwStart = GetTickCount();
  	MaxSubVectorSum1(coll.begin(), coll.end(), MaxSubSum);
  	dwEnd = GetTickCount();
  	cout << MaxSubSum << "   " << dwEnd - dwStart << endl;
 
  	dwStart = GetTickCount();
  	MaxSubVectorSum2(coll.begin(), coll.end(), MaxSubSum);
  	dwEnd = GetTickCount();
  	cout << MaxSubSum << "   " << dwEnd - dwStart << endl;

	dwStart = GetTickCount();
	MaxSubVectorSum3(coll.begin(), coll.end(), MaxSubSum);
	dwEnd = GetTickCount();
	cout << MaxSubSum << "   " << dwEnd - dwStart << endl;

	dwStart = GetTickCount();
	MaxSubVectorSum4(coll.begin(), coll.end(), MaxSubSum);
	dwEnd = GetTickCount();
	cout << MaxSubSum << "   " << dwEnd - dwStart << endl;
	return 0;
}

你可能感兴趣的:(编程珠玑)