算法导论(c++实现)chapter4

算法导论的第四章——分治策略,主要的算法为寻找最大子数组问题,还有矩阵乘法的Strassen算法,还有一些课后的练习题,主要讲了求解递归式的三种方法:代入法(感觉像是猜测,然后用数学归纳法验证),递归树法(比较的直观明了),主方法(给出了递归式的大部分通解)。现在把该chapter的所有涉及的算法都贴上来。

#include
using namespace std;

//this is the program that in order to find the max crossing subarray.
//in order to return the subarray's low bound and the high bound,
//i have to create a struct to contain all this information
//this is the constrction of the struct
template<class T>
struct SUB_Array {
    int low;
    int high;
    T sum;
};

//this is the realization of FIND-MAX-CROSSING-SUBARRAY
template<class T>
SUB_Array<T> F_M_C_S(T* A, int low, int mid, int high)
{

    T left_sum = -99999;
    T sum = 0;
    int max_left;
    for (int i = mid; i >= low; i--)
    {
        sum += A[i];
        if (sum > left_sum)
        {
            left_sum = sum;
            max_left = i;
        }
    }
    T right_sum = -9999999;
    int max_right;
    sum = 0;
    for (int j = mid + 1; j <= high; j++)
    {
        sum += A[j];
        if (sum > right_sum)
        {
            right_sum = sum;
            max_right = j;
        }
    }
    SUB_Array x;
    x.low = max_left;
    x.high = max_right;
    x.sum = left_sum + right_sum;
    return  x;
}

//this is the FIND-MAXIMUM-SUBBARRAY
template<class T>
SUB_Array<T> F_M_S(T* A, int low, int high)
{
    SUB_Array x,y,z;
    if(high==low)
    {
        x.low = low;
        x.high = high;
        x.sum = A[low];
        return x;
    }
    else
    {
      int   mid = (low + high) / 2;
        x = F_M_S(A, low, mid);
        y = F_M_S(A, mid + 1, high);
        z = F_M_C_S(A, low, mid, high);
        if (x.sum >= y.sum&&x.sum >= z.sum)
            return x;
        else if (y.sum >= x.sum&&y.sum >= z.sum)
            return y;
        else
            return z;
    }    
}


//solution to 4.1-2 . so i will use the violent way to solve the max subarray;
 template<class T>
 SUB_Array<T> Viol_Maxarray(T* A, int low, int high)
 {
     SUB_Array x;

     T Max_sum = A[low];
     int Max_low, Max_high;
     for (int i = low; i <= high; i++)
     {
         T sum = 0;
         for (int j = i; j <= high; j++)
         {
             sum += A[j];
             if (sum > Max_sum)
             {
                 Max_sum = sum;
                 Max_low = i;
                 Max_high = j;
             }
         }
     }
     x.sum = Max_sum;
     x.low = Max_low;
     x.high = Max_high;
     return x;
 }


 //solution to 4.1-4
 //in my opinion,i think the biggest subarray is that the sum must more than zero,and if the sum \
 // is less than zero,it just returns the zero ,which means not have.
 //  and it is easy to change the program ,just use the upper program,and make the left_sum=0 ,right_sum=0;


 //solution to 4.1-5
 template<class T>
 SUB_Array<T> Nrecurr_SUBARR(T* A, int low, int high)
 {
     SUB_Array x;
     int t_high;
     T Max_sum = A[low];
     int t_low=low;
     for (int i = low; i <= high; i++)
     {
         T sum = 0;
         for (int j = i + 1; j >= t_low; j--)
         {
             sum += A[j];
             if (sum > Max_sum)
             {
                 Max_sum = sum;
                 t_low = j;
                 t_high = i + 1;
             }
         }
     }
     x.low = t_low;
     x.high = t_high;
     x.sum = Max_sum;
     return x;
 }

 //this is the SQUARE-MATRIX-MULTIPLY
 const int n = 4;
 template<class T>
 void SQMA_MUL(T a[n][n], T b[n][n], T c[n][n])
 {
     for(int i=0;ifor (int j = 0; j < n; j++)
         {
             c[i][j] = 0;
             for (int k = 0; k < n; k++)
                 c[i][j] += a[i][k] * b[k][j];
         }
 }

 //this is the Strassen meathod
 //we just assure the input number is N*N,so i just split into n/2 * n/2.
 //and i didn't have much more simple coded way to realize it.
 //so i just use the ordinary way .
 //there are several steps to make ahead,so it will be sort of simple.

 const int Size = 4;
 template<class T>
 void Strassen(T a[Size][Size], T b[Size][Size], T c[Size][Size])
 {
     const int newsize = Size/2;
     T S1[newsize][newsize] = { 0 }, S2[newsize][newsize] = { 0 }, S3[newsize][newsize] = { 0 };
     T S4[newsize][newsize] = { 0 }, S5[newsize][newsize] = { 0 }, S6[newsize][newsize] = { 0 }, S7[newsize][newsize] = { 0 }, S8[newsize][newsize] = { 0 };
     T S9[newsize][newsize] = { 0 }, S10[newsize][newsize] = { 0 };
     for (int i = 0; i < newsize; i++)
         for (int j = 0; j < newsize; j++)
         {
             S1[i][j] = b[i][j+newsize] - b[newsize + i][newsize + j];
             S2[i][j] = a[i][j] + a[i][newsize + j];
             S3[i][j] = a[newsize + i][j] + a[newsize + i][newsize + j];
             S4[i][j] = b[newsize + i][j] - b[i][j];
             S5[i][j] = a[i][j] + a[newsize + i][newsize + j];
             S6[i][j] = b[i][j] + b[newsize + i][newsize + j];
             S7[i][j] = a[i][newsize + j] - a[newsize + i][newsize + j];
             S8[i][j] = b[newsize + i][j] + b[newsize + i][newsize + j];
             S9[i][j] = a[i][j] - a[newsize + i][j];
             S10[i][j] = b[i][j] + b[i][newsize + j];
         }


     T P1[newsize][newsize] = { 0 }, P2[newsize][newsize] = { 0 }, P3[newsize][newsize] = { 0 }, P4[newsize][newsize] = { 0 };
     T P5[newsize][newsize] = { 0 }, P6[newsize][newsize] = { 0 }, P7[newsize][newsize] = { 0 };
     for (int i = 0; i < newsize; i++)
         for (int j = 0; j < newsize; j++)
         {
             for (int k = 0; k < newsize; k++)
             {
                 P1[i][j] += a[i][k] * S1[k][j];
                 P2[i][j] += S2[i][k] * b[newsize + k][newsize + j];
                 P3[i][j] += S3[i][k] * b[k][j];
                 P4[i][j] += a[newsize + i][newsize + k] * S4[k][j];
                 P5[i][j] += S5[i][k] * S6[k][j];
                 P6[i][j] += S7[i][k] * S8[k][j];
                 P7[i][j] += S9[i][k] * S10[k][j];
             }
         }

     for (int i = 0; i < newsize; i++)
         for (int j = 0; j < newsize; j++)
         {
             c[i][j] = 0;
             c[i][j] = P5[i][j] + P4[i][j] - P2[i][j] + P6[i][j];
             c[i][newsize + j] = 0;
             c[i][newsize + j] = P1[i][j] + P2[i][j];
             c[i + newsize][newsize + j] = 0;
             c[i + newsize][j + newsize] = P5[i][j] + P1[i][j] - P3[i][j] - P7[i][j];
             c[newsize + i][j] = 0;
             c[newsize + i][j] = P4[i][j] + P3[i][j];
         }
 }


 int main()
 {
     //int A[16] = { 13,-3,-25,20,-3,-16,-23,18,20,-7,12,-5,-22,15,-4,7 };
     //SUB_Array x;
     //x = F_M_S(A, 0, 15);
     //x = Viol_Maxarray(A, 0, 15);
     //x = Nrecurr_SUBARR(A, 0, 15);
     //cout << x.low <<"   "<< x.high <<"   "<< x.sum << endl;

     int a[4][4] = { 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2 };
     int b[4][4] = { 1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2 };
     int c[4][4] = { 0 };
     int d[4][4];
     int e[2][2] = { 1,3,7,5 };
     int f[2][2] = { 6,8,4,2 };
    // SQMA_MUL(e, f, c);
     SQMA_MUL(a, b, d);
    Strassen<int>(a, b, c);
     for (int i = 0; i < n; i++)
     {
         for (int j = 0; j < n; j++)
             cout << c[i][j] << "  ";
         cout << endl;
     }
     cout << endl;

     for (int i = 0; i < n; i++)
     {   for (int j = 0; j < n; j++)
             cout << d[i][j] << "  ";
     cout << endl;
     }

    return 0;
}

总的算法就那么多,但是有些东西可以继续完善。有些函数的接口有待斟酌,还有就是Strassen算法,我感觉我的实现还是O(n^3),递归实现我暂时没有想出来。先上传了,等有思路在补上!欢迎大家提供思路,一起探讨~

你可能感兴趣的:(算法导论)