算法:求給定一組整數的一個子串,這個子串的和是所有子串中最大的

這個算法編程珠璣中給出了詳細的描述,但書中的代碼比較簡單,其中並沒有給出如何獲取子串的起始位置的計算。這裏給出完整的C語言實現,代碼全部在CodeBlocks下測試通過。

1.平方和算法

/* 求連續的一串數中具有最大和的子串,O(n*n)*/
int array_max_subarray_calc(int *array,int num,int *from,int *to)
{
    int i,j;
    int max = 0;
    int *sum_array = malloc(4*num);

    for(i = 0;i < num;i++)
    {
        sum_array[i] = 0;
        *from = i;

        for(j = i;j < num;j++)
        {
            sum_array[i] += array[j];
            if(sum_array[i] > max)
            {
                max = sum_array[i];
                *to = j;
                printf("max updated to %d,[%d,%d]\n",max,i,j);
            }
        }
    }

    return max;
}

 

2 分而治之算法

/* 求連續的一串數中具有最大和的子串, D&C
  [l,m],[m+1,u]
*/
int array_max_subarray_calc_DC(int *array,int l,int u,int *from,int *to)
{
    int max_l,max_m,max_u;
    int sum,max;
    int m = (l+u)/2;
    int i;
    int from_l,to_l,from_m,to_m,from_u,to_u;

    if(l > u)
        return 0;

    if(u == l)
    {
        *from = u;
        *to = u;
        return array[u];
    }

    max_l = sum = array[m];from_m = m;
    for(i = m-1;i >=l;i--)
    {
        sum += array[i];
        if(sum > max_l)
            {max_l = sum;from_m = i;}
    }

    max_u = sum = array[m+1];to_m = m+1;
    for(i = m+2;i<=u;i++)
    {
        sum += array[i];
        if(sum > max_u)
            {max_u = sum;to_m = i;}
    }

    max_m = max_l + max_u;

    max_l = array_max_subarray_calc_DC(array,l,m,&from_l,&to_l);
    max_u = array_max_subarray_calc_DC(array,m+1,u,&from_u,&to_u);

    max = MAX(max_m,max_l);
    max = MAX(max,max_u);

    if(max == max_m)
        {*from = from_m;*to = to_m;}
    else if(max == max_l)
        {*from = from_l;*to = to_l;}
    else
        {*from = from_u;*to = to_u;}

    printf("[%d,%d,%d],max_m=%d,max_l=%d,max_u=%d\n",l,m,u,max_m,max_l,max_u);

    printf("from=%d,to=%d\n",*from,*to);

    printf("------------------------------------------\n");

    return max;
}

3 一次掃描算法

/* 求連續的一串數中具有最大和的子串, 一次掃描
   max = MAX(maxsofar,maxend])*/

int array_max_subarray_On(int *array,int n,int *from,int *to)
{
    int max_sofar,max_end;
    int i;
    int from_end = -1,to_end = -1;

    max_sofar = max_end = 0;
    *from = *to = -1;

    for(i = 0;i < n;i++)
    {
        max_end = max_end + array[i];
        max_end = MAX(max_end,0);

        if(max_end > 0)
        {
            if(from_end == -1)
                from_end = i;

            to_end = i;
        }
        else
            from_end = to_end = -1;

        max_sofar = MAX(max_sofar,max_end);

        if(max_sofar == max_end)
        {
            *from = from_end;
            *to = to_end;
        }
    }

    printf("max sub array=%d,from=%d,to=%d\n",max_sofar,*from,*to);

    return max_sofar;
}
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章