1. 程式人生 > >用c++求一個二維整數陣列中最大子陣列之和(結對作業)

用c++求一個二維整數陣列中最大子陣列之和(結對作業)

題目:返回一個二維整數陣列中最大子陣列之和。

要求:

1.輸入一個二維整形陣列,數組裡有正有負。

2.二維陣列中連續的一個子矩陣 組成一個數組,每個子陣列都有一個和。

3.求所有子陣列的和的最大值。

結對程式設計要求

  1. 兩人結對完成程式設計任務。
  2. 一人負責程式分析,程式碼程式設計。
  3. 一人負責程式碼複審和程式碼測試計劃

 

通過我兩的分析,得到兩種方案。

一中是通過整體壓縮,先求出該二維整形陣列的和,然後去掉一列或一行,有四種情況。

將這進行迴圈,比較去掉之後的陣列和與沒去掉的陣列和的大小,我們取大的值,直到去掉的陣列四種情況都比比沒去掉的陣列和小,結束迴圈。(切割法)

二是通過例舉找出每個i*j矩陣的最大和,然後在這些最大和中找出最大值。(拓展法)

 

圖示:(切割法)

a(0,0)

...

...

a(0,j)

...

a(0,n)

...

...

...

...

...

...

a(i,0)

...

...

a(i,j)

...

a(i,n)

...

...

...

...

...

...

a(m,0)

...

...

a(m,j)

...

a(m,n)

四種情形:

1.

a(0,0)

...

...

a(0,j)

...

a(0,n)

...

...

...

...

...

...

a(i,0)

...

...

a(i,j)

...

a(i,n)

...

...

...

...

...

...

a(m,0)

...

...

a(m,j)

...

a(m,n)

2.

a(0,0)

...

...

a(0,j)

...

a(0,n)

...

...

...

...

...

...

a(i,0)

...

...

a(i,j)

...

a(i,n)

...

...

...

...

...

...

a(m,0)

...

...

a(m,j)

...

a(m,n)

 

3.

a(0,0)

...

...

a(0,j)

...

a(0,n)

...

...

...

...

...

...

a(i,0)

...

...

a(i,j)

...

a(i,n)

...

...

...

...

...

...

a(m,0)

...

...

a(m,j)

...

a(m,n)

4.

a(0,0)

...

...

a(0,j)

...

a(0,n)

...

...

...

...

...

...

a(i,0)

...

...

a(i,j)

...

a(i,n)

...

...

...

...

...

...

a(m,0)

...

...

a(m,j)

...

a(m,n)

四種情況與最初情形進行比較取最大值,進行迴圈直到這四種情況都比最初的小,結束迴圈。輸出該值。

 

方案二:

a(0,0)

...

...

a(0,j)

...

a(0,n)

...

...

...

...

...

...

a(i,0)

...

...

a(i,j)

...

a(i,n)

...

...

...

...

...

...

a(m,0)

...

...

a(m,j)

...

a(m,n)

先定該集合的子機的左上角為啊a(i,j),取他的b*c和c*b矩陣(i+b<n且j+c<m),每一個a(i,j)的b*c和c*b矩陣都有一個和,然後比較出b*c和c*b矩陣和的最大值,然後比較每一個c*b和b*c的最大值,得到最終的最大值。從而輸出該最大值。

b*c

a(i,j)

...

...

a(i,j+c-1)

...

...

...

...

a(i+b-1,j)

...

...

a(i+b-1,j+c-1)

c*b

a(i,j)

...

...

a(i,j+b-1)

...

...

...

...

a(i+c-1,j)

...

...

a(i+c-1,j+b-1)

一.拓展法(運算繁瑣,執行易崩,只有5*5以下的矩陣可以用。侷限性大)

 1 #include<iostream>
 2 #include<math.h>
 3 using namespace std;
 4 int A1[5][5];
 5 int max(int a, int b)
 6 {
 7     if (a > b)
 8         return a;
 9     else
10         return b;
11 }
12 int min(int a, int b)
13 {
14     if (a > b)
15         return b;
16     else
17         return a;
18 }
19 int findmax(int m[1000])
20 {
21     int max = m[0];
22     for (int i = 0; i<1000; i++)
23         if (m[i]>max)
24             max = m[i];
25     return max;
26 }
27 int sum(int x, int y, int x1, int y1)
28 {
29     int sum = 0;
30     int i, j;
31     int maxx = max(x, x1);
32     int maxy = max(y, y1);
33     int minx = min(x, x1);
34     int miny = min(y, y1);
35     for (i = minx; i <= maxx; i++)
36         for (j = miny; j <= maxy; j++)
37             sum = sum + A1[i][j];
38     return sum;
39 }
40 int findmaxarry(int A[5][5])
41 {
42     int M[1000] = { 0 }; int i = 0;
43     int a, b, c, d;
44     for (a = 0; a<5; a++)
45         for (b = 0; b<5; b++)
46             for (c = 0; c<5; c++)
47                 for (d = 0; d<5; d++)
48                 {
49                     if (a == c&&b == d)
50                     {
51                         M[i] = A[a][b]; i++;
52                     }
53                     else
54                     {
55                         M[i] = sum(a, b, c, d); i++;
56                     }
57                 }
58     return findmax(M);
59 }
60 int main()
61 {
62     
63     
64     for (int i = 0; i < 5; i++)
65     {
66         for (int j = 0; j < 5; j++)
67         {
68             cin >> A1[i][j];
69         }
70     }
71     int AllMax;
72     AllMax = findmaxarry(A1);
73     cout << AllMax << endl;
74     system("pause");
75 }

測試結果:

 

二.切割法(最終方案)

  1 #include<iostream>
  2 using namespace std;
  3 int sum_Array_lift(int **p,int m,int n,int r,int le);
  4 int sum_Array_right(int **p,int m,int n,int r,int le);
  5 int max_shu(int a,int b);
  6 int main()
  7 { 
  8   int m,n,max_sum=0;
  9   //實現整型陣列的輸入
 10   cout<<"輸入整型陣列的行長度 ";
 11   cin>>m;
 12   cout<<"輸入整型陣列的列長度 ";
 13   cin>>n;
 14   //建立一個二維陣列
 15   int ** p;
 16   p = new int *[m];
 17   for (int i = 0; i <m; i++)
 18   {
 19       p[i] = new int[n];
 20   }
 21   cout<<"輸入一個二維整型陣列"<<endl;
 22   for(int i=0;i<m;i++)
 23   {
 24       for(int j=0;j<n;j++)
 25       {    
 26           cin>>p[i][j];
 27       }
 28   }
 29   int r=0,le=0,k1=0,k2=0;
 30   max_sum=sum_Array_lift(p,m,n,r,le);
 31   while(r!=m&&le!=n)
 32   {
 33       if(r!=m)
 34       {
 35           r++;
 36           k1=max_shu(sum_Array_lift( p, m, n,r, le),sum_Array_right( p, m, n,r, le));//比較從第r行切和第n-1-r行切的值,取最大的給k1
 37           r--;
 38       }
 39       if(le!=n)
 40       {
 41           le++;
 42           k2=max_shu(sum_Array_lift( p, m, n,r, le),sum_Array_right( p, m, n,r, le));//比較從第le列切和第n-1-le列切的值,取最大的給k2
 43           le--;
 44       }
 45       if(max_sum<max_shu(k1,k2))//讓max_sum取k1和k2的最大值
 46       {
 47           max_sum=max_shu(k1,k2);
 48       }
 49       if(k1>k2)
 50       {
 51           r++;
 52           if(sum_Array_lift( p, m, n,r, le)<sum_Array_right( p, m, n,r, le))//為了不讓空間複雜度增加,我們通過改變矩陣的值 使得等同於切割後的矩陣
 53           {
 54                for(int j=0;j<n;j++)
 55               {
 56                   for(int i=m-1;i>=r;i--)
 57                   {
 58                       p[i][j]=p[i-1][j];
 59                   }
 60               }
 61           }
 62           r--;
 63       }
 64       else 
 65       {
 66           le++;
 67           if(sum_Array_lift( p, m, n,r, le)<sum_Array_right( p, m, n,r, le))//為了不讓空間複雜度增加,我們通過改變矩陣的值 使得等同於切割後的矩陣
 68           {
 69               for(int i=0;i<m;i++)
 70               {
 71                   for(int j=n-1;j>=le;j--)
 72                   {
 73                       p[i][j]=p[i][j-1];
 74                   }
 75               }
 76           }
 77           le--;
 78       }
 79       if(r!=m)
 80       {
 81           r++;
 82       }
 83       if(le!=n)
 84       {
 85           le++;
 86       }
 87       if(k1>k2)
 88       {
 89           le--;
 90       }
 91       else r--;
 92   }
 93   cout<<"二維陣列最大子陣列之和為 "<<max_sum<<endl;
 94   return 0;
 95 }
 96 int sum_Array_lift(int **p,int m,int n,int r,int le)
 97 {
 98     int sum=0;
 99     for(int i=r;i<m;i++)
100     {
101         for(int j=le;j<n;j++)
102         {
103             sum=sum+p[i][j];
104         }
105     }
106     return sum;
107 }
108 int max_shu(int a,int b)
109 {
110     if(a>b)
111     {
112         return a;
113     }
114     else return b;
115 }
116 int sum_Array_right(int **p,int m,int n,int r,int le)
117 {
118     int sum=0;
119     for(int i=m-1-r;i>=0;i--)
120     {
121         for(int j=n-1-le;j>=0;j--)
122         {
123             sum=sum+p[i][j];
124         }
125     }
126     return sum;
127 }

測試結果:

 

 

 總結

  通過自己設計的演算法,並實現。需要將難的不會的分解或轉化為我們能實現的,邏輯思維很重要。估計5個小時,實際6個小時。結對開發讓我們懂得了同伴的重要,合作的高效率。