算法導論之尋找最大子數組

bool FindMaxmumSubArray(float A[], int low, int high, float &fMaxmumSum, int &iFrom, int &iTo)
{
	// 判斷輸入條件
	if (low < 0 || high < 0 || low > high)
	{
		return false;
	}
	
	if (low == high)
	{
		iFrom = iTo = low;
		return true;
	}
	
	// 分段;
	int iMid = (low + high) / 2;
	
	// 最大子數組要麼在left ~ mid, 或 mid + 1 ~ right, 或橫跨mid的 left-right 區間;
	int iLeftFrom = 0;
	int iLeftTo = 0;
	float fLeftSum = 0.0;
	// 尋找左邊數組
	bool bLeftRes = FindMaxmumSubArray(A, low, iMid, fLeftSum, iLeftFrom, iLeftTo);
	if (!bLeftRes)
	{
		return false;
	}
	
	int iRightFrom = 0;
	int iRightTo = 0;
	float fRightSum = 0.0;
	// 尋找右邊數組
	bool bRightRes = FindMaxmumSubArray(A, iMid + 1, high, fRightSum, iRightFrom, iRightTo);
	if (!bRightRes)
	{
		return false;
	}
	
	int iCrossingFrom = 0;
	int iCrossingTo = 0;
	// 尋找橫跨mid 的子數組;
	float fCrossingSum = 0.0;
	bool bCrossingRes = FindMaxmumCrossingSubArray(A, low, mid, high, fCrossingSum, iCrossingFrom, iCrossingTo);
	if (!bCrossingRes)
	{
		return false;
	}
	
	// 如果左邊的子數組和最大
	if (fLeftSum >= fRightSum && fLeftSum >= fCrossingSum)
	{
		iFrom = iLeftFrom;
		iTo = iLeftTo;
		fMaxmumSum = fLeftSum;
	} // 如果右邊的子數組和最大
	else if (fRightSum >= fLeftSum && fRightSum >= fCrossingSum)
	{
		iFrom = iRightFrom;
		iTo = iRightTo;
		fMaxmumSum = fRightSum;
	}
	else // 最後必定是中間子數組最大;
	{
		iFrom = iCrossingFrom;
		iTo = iCrossingTo;
		fMaxmumSum = fCrossingSum;
	}
	
	return true;
}

// 尋找橫跨mid的最大子數組;
bool FindMaxmumCrossingSubArray(float A[], int low, int mid, int high, float &fCrossingSum, int &iFrom, int &iTo)
{
	if (low < 0 || high < 0 || low > high)
	{
		return false;
	}
	
	float fCurrentSum = 0.0;
	// 從mid 開始求取左邊最大和
	float fLeftMaxmumSum = -1e7;
	for (int i=mid; i>=low; i--)
	{
		fCurrentSum += A[i];
		if (fCurrentSum > fLeftMaxmumSum)
		{
			fLeftMaxmumSum = fCurrentSum;
			iFrom = i;
		}
	}
	
	// 從mid 開始求取右邊最大和
	fCurrentSum = 0.0;
	float fRightMaxmumSum = 1e-7;
	for (int i=mid+1; i<=high; i++)
	{
		fCurrentSum += A[i];
		if (fCurrentSum > fRightMaxmumSum)
		{
			fRightMaxmumSum = fCurrentSum;
			iTo = i;
		}
	}
	
	// 最大子數組的和;
	fCrossingSum = fLeftMaxmumSum + fRightMaxmumSum;
	
	return true;
}


// by 我執可破. 2016.11.10 於上海浦東;

發佈了56 篇原創文章 · 獲贊 23 · 訪問量 16萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章