矩阵的集群(数组)

时间:2015-01-09 10:45:51

标签: c arrays matrix

因此。我在C工作,我需要一些帮助。我有一个矩阵(数组)(我现在不知道如何正确翻译它:D),其中只有0和1。例如,一个可能看起来像这样: 1 1 0 0 0 0 1 1 0 1 0 0 1 0 0 0 0 1 0 0 1 1 0 1 0 0 1 0 1 1

现在。我需要从中提取包含1的集群。你能写一些关于如何处理它的想法吗?我尝试了一个结构和一个**指针,结构包含2个元素:x和y,x表示原始矩阵中的x坐标,y表示矩阵中的y坐标。然后,对于每个群集,它看起来像: cluster[0][0].x = 0; cluster[0][0].y = 0; cluster[0][1].x = 1; cluster[0][1].y = 0; cluster[0][2].x = 0; cluster[0][2].y = 1; .. 等等。但我在迭代方面遇到了一些问题(我有一个1000 * 1000的矩阵),我决定问你是否还有其他想法。感谢。

编辑:这是这个例子中的集群:

1: 1 1 0 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

2: 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

3: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 1 0 0 0

4: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 1 1

EDIT2: 所以。从1和0的矩阵,我需要提取所有相邻的" 1"' s。相邻意味着在其左上方或右上方相邻的位置。至于第一个聚类是由矩阵开头的5" 1"组成的聚类。另一个群集只包含一个" 1"在第2行第4列。我需要以某种方式将每个群集的x和y坐标存储在某处,因为我需要稍后使用它们。

2 个答案:

答案 0 :(得分:0)

对于字符串数据,只是一个数组

char  map[1000][1000]

这将使用1兆字节的内存,这些日子并不多。

我看到的算法是

  1. 在矩阵中找到1
  2. 对其进行填充(例如,将1更改为20
  3. 然后继续搜索矩阵中的1
  4. 返回转换所有1 s所需的填充次数。

    Flood填充是众所周知的算法,您应该能够找到合适的示例,或者可能使用图形库。

答案 1 :(得分:0)

一个简单的实施

使用回溯来获取所有集群,让我们从(0,0)开始作为示例,我们首先检查(0,0)是否为1,如果是,则逐个检查其邻居。如果其中一个邻居是1,那么移动到那里并以相同的方式检查。这个过程不会停止,直到位置的四个方向邻居全部为0或被访问。

要记录我们访问过的位置,我们需要一个与原始数组大小相同的标志映射。

此外,为了绘制每个集群,在回溯过程中,我们同时记录每个位置,我选择一组列表来保存集群中的所有位置。

这里是所有代码,包括你发布的测试用例

 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>

 #define MAX_COL        6
 #define MAX_ROW        5
 #define MAX_SIZE   (MAX_COL * MAX_ROW) 

 int a[5][6] = {
    1, 1, 0, 0, 0, 0,
    1, 1, 0, 1, 0, 0,
    1, 0, 0, 0, 0, 1,
    0, 0, 1, 1, 0, 1,
    0, 0, 1, 0, 1, 1,
};

int dir_x[4] = {0, 1, 0, -1};
int dir_y[4] = {1, 0, -1, 0};

struct point {
    int x;
    int y;
};

struct node {
    struct point pos;
    struct node *next;
};

struct node* cluster_set[MAX_SIZE];
int cluster_set_index = 0;

int is_inside(int height, int width, int i, int j)
{
    if (0 <= j && j < width && i >= 0 && i < height)
        return 1;
    return 0;
}

int cluster_check(int (*matrix)[MAX_COL], int height, int width, int row, int col, int (*flag_matrix)[MAX_COL], struct node* head)
{
    int i, tmp_x, tmp_y;
    flag_matrix[row][col] = 1;

    for (i = 0; i < 4; i++)
    {
        tmp_x = row + dir_x[i];
        tmp_y = col + dir_y[i];
        if (is_inside(height, width, tmp_x, tmp_y) && matrix[tmp_x][tmp_y] && !flag_matrix[tmp_x][tmp_y]) {
            flag_matrix[tmp_x][tmp_y] = 1;
            struct node *new_node = (struct node*)malloc(sizeof(struct node));
            assert(new_node != NULL);
            new_node -> pos.x = tmp_x; 
            new_node -> pos.y = tmp_y; 
            new_node -> next = NULL;
            head -> next = new_node;
            cluster_check(matrix, height, width, tmp_x, tmp_y, flag_matrix, new_node);
        }
    }
}

int cluster_count(int (*matrix)[MAX_COL], int height, int width)
{
    int count = 0, i, j;
    int flag_matrix[MAX_ROW][MAX_COL] = {0};

    for (i = 0; i < height; i++)
        for (j = 0; j < width; j++)
        {
            if (matrix[i][j] && !flag_matrix[i][j]) {
                count++;
                struct node *new_node = (struct node*)malloc(sizeof(struct node));
                assert(new_node != NULL);
                new_node -> pos.x = i; 
                new_node -> pos.y = j; 
                new_node -> next = NULL;
                cluster_set[cluster_set_index++] = new_node;
                cluster_check(matrix, height, width, i, j, flag_matrix, new_node);
            }
        }
    return count;
}

void print_cluster(int (*map)[MAX_COL], int row, int col)
{
    int i, j;
    for (i = 0; i < row; i++)
    {
        for (j = 0; j < col; j++)
            printf("%2d ", map[i][j]);
        printf("\n");
    }
    printf("\n");
}


int main()
{
    printf("total clusters: %d\n", cluster_count(a, 5, 6));
    int i, cluster_map[MAX_ROW][MAX_COL] = {0};
    struct node *tmp;
    for (i = 0; i < cluster_set_index; i++)
    {
        tmp = cluster_set[i];
        while (tmp != NULL) {
            printf("(%d, %d)", tmp->pos.x, tmp->pos.y);
            cluster_map[tmp->pos.x][tmp->pos.y] = 1;
            tmp = tmp -> next;
        }
        printf("\n");
        print_cluster(cluster_map, MAX_ROW, MAX_COL);
        memset(cluster_map, 0x00, sizeof(int)*MAX_ROW*MAX_COL); 
    }
}

这是正在运行的结果,只需忽略您不需要的信息

total clusters: 4
(0, 0)(0, 1)(1, 1)(1, 0)(2, 0)
 1  1  0  0  0  0
 1  1  0  0  0  0
 1  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0

(1, 3)
 0  0  0  0  0  0
 0  0  0  1  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0

(2, 5)(3, 5)(4, 5)(4, 4)
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  1
 0  0  0  0  0  1
 0  0  0  0  1  1

(3, 2)(4, 2)
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  0  0  0  0
 0  0  1  0  0  0
 0  0  1  0  0  0