分治算法(用C++、lua实现)

摘要:
目录1,算法2,C++实现3,lua实现这是分治算法的代码实现。作者很穷。请原谅我的任何错误。1.算法的分而治之策略是:对于一个规模为n的问题,如果该问题可以很容易地解决(例如,n的规模很小),则可以直接解决;否则,可以将其分解为k个子问题,这些子问题彼此独立,并且具有与原问题相同的形式,递归地求解这些子问题,然后将每个子问题的解组合起来,得到原问题的解。这种算法设计策略称为分而治之。可以用分而治之(1)二分法解决的一些经典问题

目录




本文为 分治算法 的代码实现。
作者水平比较差,有错误的地方请见谅。
1、算法

分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。

可使用分治法求解的一些经典问题
(1)二分搜索
(2)大整数乘法
(3)Strassen矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择
(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔

此例子为使用分治法,来求一个数组中的最大连续子段。
分治算法(用C++、lua实现)第1张
连续子段为:-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)


免责声明:文章转载自《分治算法(用C++、lua实现)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇mysql 修改表引擎方法go 安装下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

浅谈CDQ分治

很久前就想写篇CDQ分治的blog了,现在填坑。 CDQ分治是一种分治算法,一般用于高维数据结构的降维。比如二维数据结构,可以通过CDQ分治变成一个一维的问题。 CDQ分治本质还是个分治。一般分治操作就是,我想知道一个长度为n的区间产生的贡献有多少,那我可以把区间平均划分成两部分,那么此时问题变成左区间产生的贡献+右区间产生的贡献+左区间对右区间产生的贡献...