本文为 分治算法 的代码实现。
作者水平比较差,有错误的地方请见谅。
1、算法
分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。
可使用分治法求解的一些经典问题
(1)二分搜索
(2)大整数乘法
(3)Strassen矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择
(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔
此例子为使用分治法,来求一个数组中的最大连续子段。
连续子段为:-23,18,20,-7,12
最大值为:-23+18+20-7+12 = 43
2、C++实现
暴力求解
#include <iostream>
using namespace std;
int main()
{
//求最大的连续子段和
int sumArray[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
int length = sizeof(sumArray)/sizeof(sumArray[0]);
int startIndex = 0;
int endIndex = 0;
int maxArray = sumArray[0];
for(int i=0;i<length;i++){
int tempPrice = 0;
for(int j=i;j<length;j++){
tempPrice += sumArray[j];
if(tempPrice>maxArray)
{
maxArray = tempPrice;
startIndex = i;
endIndex = j;
}
}
}
cout<<"最大数组首index:"<<startIndex<<endl;
cout<<"最大数组尾index:"<<endIndex<<endl;
cout<<"最大值"<<maxArray<<endl;
return 0;
}
分治算法
#include <iostream>
using namespace std;
///结构体存储开始下标、结束下标、区间和
struct SubArray
{
int startIndex;
int endIndex;
int totalNum;
};
SubArray GetMaxArray(int arr[],int low,int high);
int main()
{
//求最大的连续子段和
int myArray[] = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7};
int length = sizeof(myArray)/sizeof(myArray[0]);
SubArray subArray = GetMaxArray(myArray,0, length-1);
cout<<"首index:"<<subArray.startIndex<<endl;
cout<<"尾index:"<<subArray.endIndex<<endl;
cout<<"最大值"<<subArray.totalNum<<endl;
return 0;
}
SubArray GetMaxArray(int arr[],int low,int high)
{
if (low == high)
{
SubArray subArray;
subArray.startIndex = low;
subArray.endIndex = high;
subArray.totalNum = arr[low];
return subArray;
}
int mid = (low + high) / 2;
//左区间的最大子段
SubArray subArrayLeft = GetMaxArray(arr,low, mid);
//右区间的最大子段
SubArray subArrayRight = GetMaxArray(arr,mid + 1, high);
//左下标在左区间右下标在右区间的最大字段
SubArray subArrayAll;
//计算subArrayAll的左半最大部分
int allMaxLeft = arr[mid] ;
int leftIndex = mid;
int tempNum = 0;
for (int i = mid; i >= low; i--)
{
tempNum += arr[i];
if (tempNum > allMaxLeft)
{
allMaxLeft = tempNum;
leftIndex = i;
}
}
//计算subArrayAll的右半最大部分
int allMaxRight = arr[mid + 1];
int rightIndex = mid + 1;
tempNum = 0;
for (int j = mid + 1; j <= high; j++)
{
tempNum += arr[j];
if (tempNum > allMaxRight)
{
allMaxRight = tempNum;
rightIndex = j;
}
}
subArrayAll.totalNum = allMaxLeft + allMaxRight;
subArrayAll.startIndex = leftIndex;
subArrayAll.endIndex = rightIndex;
//三者比较,谁的值最大
if (subArrayLeft.totalNum >= subArrayRight.totalNum && subArrayLeft.totalNum >= subArrayAll.totalNum)
{
return subArrayLeft;
}
else if (subArrayRight.totalNum >= subArrayLeft.totalNum && subArrayRight.totalNum >= subArrayAll.totalNum)
{
return subArrayRight;
}
else
{
return subArrayAll;
}
}
3、lua实现
myArray = {13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7}
length = #myArray
function GetMaxArray(arr,low,high)
if(low == high) then
local subArrayTemp = {}
subArrayTemp.startIndex = low
subArrayTemp.endIndex = high
subArrayTemp.totalNum =arr[low]
return subArrayTemp;
end
--mid不能为浮点数,向下取整
local mid = math.floor((low+high)/2)
--左区间最大子段
local subArrayLeft = GetMaxArray(arr,low,mid)
--右区间最大子段
local subArrayRight = GetMaxArray(arr,mid+1,high)
--左下标在左区间右下标在右区间的最大字段
local subArrayAll = {}
--计算subArrayAll的左半最大部分
local allMaxLeft = arr[mid]
local leftIndex = mid
local tempNum = 0
for i=mid,low,-1 do
tempNum = tempNum + arr[i]
if(tempNum > allMaxLeft) then
allMaxLeft = tempNum
leftIndex = i
end
end
--计算subArrayAll的右半最大部分
local allMaxRight = arr[mid+1]
local rightIndex = mid+1
tempNum = 0
for i=mid+1,high,1 do
tempNum = tempNum + arr[i]
if(tempNum > allMaxRight) then
allMaxRight = tempNum
rightIndex = i
end
end
subArrayAll.startIndex = leftIndex
subArrayAll.endIndex = rightIndex
subArrayAll.totalNum = allMaxLeft + allMaxRight
--比较三者谁的值最大
if (subArrayLeft.totalNum >= subArrayRight.totalNum and subArrayLeft.totalNum >= subArrayAll.totalNum) then
return subArrayLeft
elseif (subArrayRight.totalNum >= subArrayLeft.totalNum and subArrayRight.totalNum >= subArrayAll.totalNum) then
return subArrayRight
else
return subArrayAll
end
end
--自定义比较两个整数函数
function MaxNum(num1,num2)
if(num1>num2) then
return num1
end
return num2
end
subArray = GetMaxArray(myArray,1,length)
print("首index:" .. subArray.startIndex)
print("尾index:" .. subArray.endIndex)
print("最大值:" .. subArray.totalNum)