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






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

    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)
    
    
    
  • 相关阅读:
    计算后的样式
    getElementsByTagName
    notepad++ 行首行尾添加字符
    Http协议基础知识
    HTTP工作流程
    URI URL URN的区别
    [转] Android利用Fiddler进行网络数据抓包
    微信公众号 跳转到小程序
    现金红包 接口开发注意事项
    现金红包 样式问题
  • 原文地址:https://www.cnblogs.com/Fflyqaq/p/11825313.html
Copyright © 2020-2023  润新知