1

So. I am working in C and I need some help. I have a matrix(array) (I do not now how to translate it right :D ) that has only 0 and 1 in it. For example, one could look like this: 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

Now. I need to extract from it the clusters that contain 1. Can you write me some ideas on how to approach this? I tried with a structure and a **pointer to it, with the structure containing 2 elements : x and y, x for x coordinate in the original matrix and y for the y coordinate in the matrix. Then, for each cluster, it would look like : 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; .. and so on. But I have some problems with the iteration( I have a 1000*1000 matrix) and I decided to ask you if you have any other ideas. Thanks.

EDIT: These are the clusters in this example:

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: So. From that matrix of 1 and 0 and I nee to extract all groups of adjacent "1"'s. Adjacent means neighbouring on either up down left or right from it's position. As for the first cluster would be the one made up from those 5 "1"'s from the beginning of the matrix. Another cluster would be that that contains only one "1" on line 2 column 4. And I need somehow to store the x and y coordinate of each cluster somewhere, as I need to use them later on.

  • 1
    What is a "cluster" here? Anything `1` with an adjacent `1` in any direction? –  Jan 09 '15 at 10:49
  • Yes, but only up down left right, not in diagonal. For that example there are 4 clusters. – Lazar Lucian-Ionut Jan 09 '15 at 10:50
  • You are on the (a) right track though: you can step through the elements of a 2D matrix in a double loop, and for every element that is a `1`, look left and right, up and down (`+1`, `-1` to the row or column index) to see if it contains a `1` as well. There are probably smarter ways, but this would be the most straightforward way. You'll need another matrix to keep track of elements already belonging to a cluster. –  Jan 09 '15 at 10:51
  • So how is the number of clusters here is 4? I don't get it – Gopi Jan 09 '15 at 11:03
  • Sure. So. From that matrix of 1 and 0 and I nee to extract all groups of adjacent "1"'s. Adjacent means neighbouring on either up down left or right from it's position. As for the first cluster would be the one made up from those 5 "1"'s from the beginning of the matrix. Another cluster would be that that contains only one "1" on line 2 column 4. And I need somehow to store the x and y coordinate of each cluster somewhere, as I need to use them later on. – Lazar Lucian-Ionut Jan 09 '15 at 11:12
  • http://stackoverflow.com/questions/367226/flood-fill-algorithms – 2501 Jan 09 '15 at 11:40
  • hey guy, how about my answer? – simon_xia Jan 15 '15 at 13:23

2 Answers2

0

For string the data, just an array

char  map[1000][1000]

that'll use 1 megabyte of memory, which is not a lot these days.

An algorithm as I see it is

  1. find a 1 in the matrix,
  2. do a flood-fill on it (eg changing 1 to 2 or to 0)
  3. then continue searhcing for a 1 in the matrix.

return the number of fills needed to convert all the 1s.

Flood fill is a well known algorithm, you should be able to find a suitable example, or possibly use a graphics library.

Jasen
  • 11,837
  • 2
  • 30
  • 48
0

A simple implemention

Use the backtracking to get all clusters, let's start from (0,0) as an example, we first check if (0,0) is 1, if so, check its neighbors one by one. If one of the neighbors is 1, move there and check in the same way. this process doesn't stop until the position's four direction neighbors are all 0 or visited.

To record the position we visited, we need a flag map which has the same size as origin array.

Besides, to draw each cluster, during the backtracking, we record each postion at the same time, I choose a set of list to save all positions in a cluster.

here is all code, including test case you post

 #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); 
    }
}

and here is the running results, just ignore the infomation you don't need

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
simon_xia
  • 2,394
  • 1
  • 20
  • 32