编程珠玑第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; }