算法设计技术

算法设计技术

问题:问题的输入是具有n个浮点数的向量x,输出是输入向量的任何连续子向量中的最大和。例如,如果输入向量包含下面10个元素:31-41,59,26-53,58,97-93-23,84

代码:

float arr[] = { 31, -41, 59, 26, -53, 58, 97, -93, -23, 84 };

// 立方算法  时间复杂度为T(n) = O(n^3)

float CubeMaxSubSum(const float *arr, const int N , int &begin , int &end)

{

    float maxsofar = 0 ;

    for (int i = 0; i < N; i++)

    {

        for (int j = i; j < N; j++)

        {

            float sum = 0;

            for (int k = i; k <= j; k++)

            {

                sum += arr[k];

            }

            if (sum > maxsofar)

            {

                maxsofar = sum;

                begin = i;

                end = j;

            }

        }

    }

    return maxsofar;

}

// 平方算法1  时间复杂度T(n)=O(n^2);

float SquareMaxSubSum(const float *arr, const int N, int &begin, int &end)

{

    float maxsofar = 0;

    for (int i = 0; i < N; i++)

    {

        float sum = 0;

        for (int j = i; j < N; j++)

        {

            sum += arr[j];

            if (sum > maxsofar)

            {

                maxsofar = sum;

                begin = i;

                end = j;

            }

        }

    }

    return maxsofar;

}

#define N 10

// 平方算法2  时间复杂度T(n)=O(n^2);

float SquareTMaxSubSum(const float *arr, const int n, int &begin, int &end)

{

    /*

     * 下面3行代码解决 cumarr[-1] 的问题

     */

    float realsum[N + 1] = { 0 };

    float *cumarr = realsum + 1;

    cumarr[-1] = 0;

    for (int i = 0; i < n; i++)

    {

        cumarr[i] = cumarr[i - 1] + arr[i];

    }

    float maxsofar = 0;

    for (int i = 0; i < n; i++)

    {

        float sum = 0;

        for (int j = i; j < n; j++)

        {

            sum = cumarr[j] - cumarr[i-1];

            if (sum > maxsofar)

            {

                maxsofar = sum;

                begin = i;

                end = j;

            }

        }

    }

    return maxsofar;

}

float max(float a, float b)

{

    return a > b ? a : b;

}

// 分治算法 时间复杂度T(n)=O(nlogn);

/************************************************************************/

/*

算法说明:

*1)当所有输入都是正数时,最大子向量就是整个输入向量

*2)当所有输入都是负数时,最大子向量是空向量,和为0

*3)当前处理情况是,输入序列有正有负

*/

/************************************************************************/

float DivideMaxSubSum(const float *arr, int left , int right)

{

    if (left > right)

        return 0;

    if (left == right)

        return 0 > arr[left] ? 0 : arr[left];

    int middle = (left + right) / 2;

    float lmax = 0, sum = 0;

    for (int i = middle; i >= left; i--)

    {

        sum += arr[i];

        lmax = lmax > sum ? lmax : sum;

    }

    float rmax = 0;

    sum = 0;

    for (int j = middle + 1; j <= right; j++)

    {

        sum += arr[j];

        rmax = rmax > sum ? rmax : sum;

    }

    return max(max((lmax + rmax), DivideMaxSubSum(arr , left, middle)), DivideMaxSubSum(arr , middle + 1, right));

}

// 扫描算法 时间复杂度T(n)=O(n);

float ScanMaxSubSum(const float *arr, const int n )

{

    float maxSoFar = 0, maxEndInHere = 0;

    //该问题的关键在于maxEndInHere变量,它是结束位置i-1之前的最大子向量之和

    for (int i = 0; i < n; i++)

    {

        maxEndInHere = max(maxEndInHere + arr[i], 0);

        maxSoFar = max(maxSoFar, maxEndInHere);

    }

    return maxSoFar;

}

int main(int argc, char *argv[])

{

    QCoreApplication a(argc, argv);

    int begin = -1, end = -1;

    int k = ScanMaxSubSum(arr, 10);

    printf("k = %d\n", k);

    return a.exec();

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值