查找给定二维二进制矩阵中连接对象的数量

时间:2017-06-05 11:53:24

标签: c

从给定的2d矩阵中查找连接对象的数量
 样本输入&输出1:

Enter number of rows: 
5 
Enter number of columns: 
5 
Enter the matrix: 
0 0 0 0 0
1 0 0 1 0
1 0 0 0 1
0 1 0 1 0
0 0 0 0 0 
Number of connected objects = 2

2 个答案:

答案 0 :(得分:0)

我发现了你想要的东西,在这里你知道了,这解释了如何找到" islands",意思是连接1的数量

http://www.geeksforgeeks.org/find-number-of-islands/

答案 1 :(得分:0)

像这样

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

typedef int Color;

typedef struct cell {
    char kind;
    Color color;
} Cell;

typedef struct pos {//position
    int h, v;
} Pos, Size;

typedef struct world {
    Size size;
    Cell **cells;
} World;

typedef struct node {
    Pos pos;
    struct node *next;
} Node;

typedef struct stack {
    Node *np;
} Stack;

void push(Stack *s, Pos pos){
    Node *np = malloc(sizeof(*np));
    np->pos = pos;
    np->next = s->np;
    s->np = np;
}
int isEmpty(Stack *s){
    return !s->np;
}

Pos pop(Stack *s){
    Pos ret = s->np->pos;
    Node *next = s->np->next;
    free(s->np);
    s->np = next;
    return ret;
}

World *make_world(Size size, Stack *s);
void ruin(World *w);
void paint(World *w, Pos pos, Color *color);

int main(void){
    int rows, cols;

    puts("Enter number of rows:");
    scanf("%d", &rows);

    puts("Enter number of columns:");
    scanf("%d", &cols);

    Stack land = { NULL };
    World *world = make_world((Size){.v = rows, .h = cols}, &land);

    Color color = 0;
    while(!isEmpty(&land)){//`land` is a position list of `1`
        paint(world, pop(&land), &color);//Paint the same color from the specified position. New location paints another color(do increment color)
    }
    printf("Number of connected objects = %d\n", color);//The number of colors used is the number of connected objects.
    ruin(world);
}

enum { BLANK = 0, LAND = '1', SEA = '0', NONE = -1 };

World *make_world(Size size, Stack *landList){
    World *w = malloc(sizeof(*w));
    w->size = size;
    w->cells = malloc(size.v * sizeof(*w->cells));
    for(int r = 0; r < size.v; ++r){
        w->cells[r] = calloc(size.h, sizeof(**w->cells));
    }
    puts("Enter the matrix:");
    for(int r = 0; r < size.v; ++r){
        for(int c = 0; c < size.h; ++c){
            char ch = 0;
            scanf(" %c", &ch);
            if((w->cells[r][c].kind = ch) == LAND)
                push(landList, (Pos){ .v = r, .h = c});
        }
    }
    return w;
}

void ruin(World *w){
    for(int r = 0; r < w->size.v; ++r)
        free(w->cells[r]);
    free(w->cells);
    free(w);
}

void fill(World *w, Pos pos, Color *color, Cell *neighbor){
    if(pos.h < 0 || pos.v < 0 || pos.h >= w->size.h || pos.v >= w->size.v)//Out of range
        return;
    Cell *cell = &w->cells[pos.v][pos.h];//reduce code
    if(cell->color != BLANK)//Color already painted
        return;
    if(neighbor != NULL){//There are adjacent cells
        if(cell->kind != neighbor->kind){//Do not process unless they are of the same kind
            return;
        }
        cell->color = neighbor->color;//Fill with the color of the adjacent cell
    } else {
        cell->color = ++*color;//The first cell paints a new color.
    }
    //Process my own neighbor cell
    fill(w, (Pos){.v = pos.v-1, .h = pos.h-1}, color, cell);
    fill(w, (Pos){.v = pos.v-1, .h = pos.h  }, color, cell);
    fill(w, (Pos){.v = pos.v-1, .h = pos.h+1}, color, cell);
    fill(w, (Pos){.v = pos.v  , .h = pos.h-1}, color, cell);
//  fill(w, (Pos){.v = pos.v  , .h = pos.h  }, color, cell);//current cell
    fill(w, (Pos){.v = pos.v  , .h = pos.h+1}, color, cell);
    fill(w, (Pos){.v = pos.v+1, .h = pos.h-1}, color, cell);
    fill(w, (Pos){.v = pos.v+1, .h = pos.h  }, color, cell);
    fill(w, (Pos){.v = pos.v+1, .h = pos.h+1}, color, cell);
}

void paint(World *w, Pos pos, Color *color){//wrapper function
    fill(w, pos, color, NULL);
}