在2D阵列中查找最大的簇

时间:2014-11-18 16:52:18

标签: c arrays 2d

我必须在二维数组中找到一个集群。这意味着我必须找到最大数量的" 1"在二维数组中。只有" 0"和" 1"在数组中。连接的号码可以全部" 1"在每个方向(8个方向) 例如,该矩阵具有6的簇

示例:输出= 6



ma[] = { 1, 1, 0, 0, 0,
         1, 1, 0, 0, 0,
         0, 0, 1, 0, 0,    //because of diagonal
         0, 1, 0, 0, 1 };   // the last "1" should not be counted 




不幸的是,我不知道该怎么做。这是我的最新代码,我可以计算所有" 1"在2d数组中。



void cluster(int *mat, int rows, int cols) { 
    int i, j;
    int target = 0;
    printf("\n+++++++++++++++++++++++++++++++\nbiggst cluster\n\n");
    for(j = 0; j < cols; j++) { 
        for (i = 0; i < rows; i++) {
	    if (mat[j*rows+i] == 1)
		target = target + 1;
        }
    }
printf("%d ", target);
}
&#13;
&#13;
&#13;

我真的很感激一个小代码或算法来解决这个问题。

迎接

3 个答案:

答案 0 :(得分:1)

通过首先定义和陈述目标,然后将其分解为解决所需的步骤,可以解决问题:

首先,对您的问题陈述进行一些澄清:

以下 未定义2D矩阵 ,它是作为具有20个元素的单维数组创建的

ma[] = { 1, 1, 0, 0, 0,
         1, 1, 0, 0, 0,
         0, 0, 1, 0, 0,    //because of diagonal
         0, 1, 0, 0, 1 };   // the last "1" should not be counted 

二维数组中“1”的最大数量
假设您的意思是 数组中具有值== 1 的相邻元素的数量

数字在每个方向(8个方向)上都可以是“1”
C阵列中只有两个方向 。 (见下面的解释)

为清楚起见,修改一些定义:
1)定义一组值:
   一个簇是一个或多个包含值1的数组元素,并且在任何方向上相邻到另一个数组元素。 (见下面相邻的评论)
2)在C中定义一个2D数组:    C中的2D数组是连续存储器的一个区域,其中数组元素以行主要方式排列:

Example: int array[4][5] = {{1,0,0,0,0},{0,1,0,0,0},{0,0,1,0,0},{0,0,0,1,0}};  

概念上看起来像这样:

|1|0|0|0|0|    
|0|1|0|0|0|     
|0|0|1|0|0|    
|0|0|0|1|0|  //cluster of four

但在记忆中看起来像这样:

|1|0|0|0|0|0|1|0|0|0|0|0|1|0|0|0|0|0|1|0|  //cluster of zero  (no "1" elements next to another)
|         |         |         |       |              
[0][0]    [1][0]    [2][0]    [3][0]  [3][4]      

请注意,实际上, Adjacent 采用不同的视角。

因此预期解决方案与相邻内存几乎没有关系,更多与数组表示法有关,例如[i][j]

为了您的目的,相邻应定义为:
元素索引的接近度,其中另一个元素在任何方向上最多1个索引:

给定array[ROWS][COLS];

以下是邻接测试 :(使用我们的定义)

在以下情况下,

array[m][n]array[o][p]相邻:

  • !((m == o)&amp;&amp;(n == p))//相同元素
  • (abs(m-o)&lt; = 1)&amp;&amp; (abs(n-p)&lt; = 1)
  • ((m + o)&lt; ROWS)&amp;&amp;((n + p)&lt; COLS)

问题可以通过逐行遍历所有元素来解决,并通过查看每个周围的索引来测试每个元素与其他元素的接近程度。

答案 1 :(得分:0)

有更多内存有效的方法,但是:您可以构建另一个具有相同大小的矩阵并将其初始化为全零。设这个矩阵为B。

开始扫描第一个矩阵A,计数器N初始化为1,并且一旦在A a&#34; 1&#34;有一个&#34; 0&#34;在B中(即Aij = 1,Bij = 0),将其放入列表并将M初始化为0.

然后直到列表为空:

  • 从列表中弹出一个项目并递增M.
  • 看看它的邻居(你只需要(x-1,y),(x + 1,y),(y + 1,x-1),(y + 1,x)和(y + 1, x + 1))如果他们有Ax&#39; y&#39; = 1和Bx&#39; y&#39; = 0,设置Bx&#39; y&#39;到N并将它们添加到列表中。

当列表为空时,您已在群集N中找到M个元素,因此请设置ClusterSize[N]=M

完成后,找到ClusterSize的最大值,假设这是ClusterSize [K];那么Bij = K的所有元素都属于基数M的簇。

算法访问所有矩阵项。群集阵列最多需要W H / 4个元素(你不能拥有超过WH / 4个1个项目的群集而没有一些项目连接和减少群集的数量),最多W H表示AncillaryMatrix,W * H表示List。您可以随意动态分配和重新分配它们,但除非有必要保存内存,否则我只能使用悲观值。

伪代码:

int **AncillaryMatrix;

if (NULL == (AncillaryMatrix = malloc(sizeof(int *)*H))) {
    return ERROR_OUTOFMEMORY;
}
for (j = 0; j < H; j++) {
    if (NULL == (AncillaryMatrix[j] = malloc(sizeof(int)*W))) {
        while (--j) {
             free(AncillaryMatrix[j]); AncillaryMatrix[j] = NULL;
        }
        free(AncillaryMatrix); AncillaryMatrix = NULL;
        return ERROR_OUTOFMEMORY;
    }
    for (i = 0; i < W; i++) {
        AncillaryMatrix[j][i] = 0;
    }
}
N = 1;
for (j = 0; j < H; j++) {
    for (i = 0; i < W; i++) {
        if (0 == BaseMatrix[j][i]) {
            continue;
        }
        if (0 != AncillaryMatrix[j][i]) {
            continue;
        }
        if (0 == (Cluster[N] = FillMatrix(BaseMatrix, AncillaryMatrix, W, H, i, j, N)) {
            // Handle out of memory error.
        }
        N++;
    }
}
// Free ancillarymatrix, unless you need to know the items in the K-th cluster
j = H; while (j--) {
     free(AncillaryMatrix[j]); AncillaryMatrix[j] = NULL;
}
free(AncillaryMatrix); AncillaryMatrix = NULL;

// Find maximum value in Cluster[1..N-1].
// Cluster[0] is not used because "0" in AncillaryMatrix means "no cluster here"
// So the number of clusters is really N-1.
for (j = 1, i = 2; i < N; i++) {
     if (Cluster[i] > Cluster[j]) {
         j = i;
     }
}
// Largest cluster identified by j, has Cluster[j] members.

////

int FillMatrix(int **B, int **A, int W, int H, int i, int j, int N) {
    int M = 0;
    typedef struct Item { int x, int y } *List;
    if (null == (List = malloc(sizeof(Item)*W*H))) {
         return 0;
    }
    List[l].x = i;
    List[l].y = j;
    A[j][i] = N;
    l++;
    while (l) {
        l--; M++;
        int ii = List[l].x;
        int jj = List[l].y;
        // Add neighbours. NOTE: add code to handle case when jj or ii is 0
        // or jj is H-1 or ii is W-1.

        // check jj,ii-1 (could use a macro)
        if (B[jj][ii-1]) {
            if (0 == A[jj][ii-1]) {
                List[l].x = ii-1;
                List[l].y = jj;
                l++;
            }
        }
        CHECK(jj, ii+1)
        CHECK(jj+1, ii-1)
        CHECK(jj+1, ii)
        CHECK(jj+1, ii+1)
    }
    free(List); // List = NULL;
    return M;
}

答案 2 :(得分:0)

伙计们,我终于找到了一个非常简单的解决方案来解决这个问题,只需看看......

void cluster(int rows, int cols) { 

    int ma4[4][5] = {{0, 1, 0, 0, 0}, // 1. Zeile
                     {1, 1, 0, 0, 0}, // 2. Zeile
                     {1, 1, 0, 1, 0}, // 3. Zeile
                     {0, 1, 0, 0, 0}};  // 4. Zeile
    int i = 0;
    int j = 0;
    int target = 0;
    printf("\n+++++++++++++++++++++++++++++++\nbiggst cluster\n\n");
    for(j = 0; j < cols; j++) { 
        for (i = 0; i < rows; i++) {
	    if (ma4[j][i] == 1) {
		if (ma4[j-1][i] || ma4[j][i-1] || ma4[j+1][i] || ma4[j][i+1] || ma4[j-1][i-1] || ma4[j+1][i+1] || ma4[j-1][i+1] || ma4[j+1][i-1] == 1)
		   target += 1;
            }
        }
        
    
    }
printf("%d ", target);
}