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 於上海浦東;