搜索2d阵列中最大的空间

时间:2015-12-15 22:37:18

标签: c# algorithm

Screen shot

我有随机颜色发生器。正如你在照片中看到的,它会随机生成一种颜色(R - 红色,G - 绿色,Y - 黄色)。

我需要找到占据最大空间的颜色。但有一个条件。我可以算出那个颜色最大的空间,它有很多相同的邻居。我不知道怎么说,英语不是我的主要语言。

例如,RGYRGYRGRGRGRGRGR红色不会占据最大的空间,因为它彼此分开。但是RRRRRRRRGYGYG很好,因为所有的R颜色都在附近。

我该怎么办?起初我认为我需要使用广度优先搜索算法。但是我的教授说我可以“扫描”行或列。所以我不知道该怎么做。哪种方式最简单?

3 个答案:

答案 0 :(得分:5)

您是否正在寻找相邻同色元素的最大斑点?在这种情况下,与https://en.wikipedia.org/wiki/Flood_fill相反的东西可能是最简单的。从每个位置开始,看看在到达边界之前可以走多远。您之前已经添加的地点" fill"不需要再次检查。

答案 1 :(得分:2)

connected-component labeling个算法,它们旨在解决此类问题 Wiki页面主要用于二进制大小写,但也存在用于从多色图片中提取blob的算法实现。

答案 2 :(得分:0)

这是我几个月前写的一个用C编写的算法,如果我有时间,我会转换成C#。

#include <stdio.h>

int find_root(int index, int *roots) {
    // index = i * height + j
    if (roots[index] == index) return index;
    else {
        int root = find_root(roots[index], roots);
        roots[index] = root;
        return root;
    }
}

void process(char matrix[], long width, long height) {

    long number_of_pixels = height * width;

    int *roots = (int *)malloc(number_of_pixels * sizeof(int));
    // roots[width * i + j] points the root of area where i, j belongs to

    int *connectivities = (int *)malloc(number_of_pixels * sizeof(int)); 
    // connectivities explain:
    // 1  -> isolated, 
    // 0  -> non-isolated, non-root, 
    // >1 -> non-isolated, root

    // only consider left and upper sides!!!
    const int connects[2][2] = {
        {-1, 0},
        {0, -1}
    };

    for (long i = 0; i < number_of_pixels; ++i) {
        roots[i] = i;
        connectivities[i] = 1;
    }

    for (long i = 0; i < height; ++i) {
        for (long j = 0; j < width; ++j) {
            for (int k = 0; k < 2; ++k) {
                long neighbor_j = j + connects[k][0];
                long neighbor_i = i + connects[k][1];
                if (neighbor_j >= 0 && neighbor_j < width
                    && neighbor_i >= 0 && neighbor_i < height
                    && matrix[width * neighbor_i + neighbor_j] == matrix[width * i + j]) {
                    // join it to neighbor group
                    long root = find_root(i * width + j, roots);
                    long neighbor_root 
                        = find_root(width * neighbor_i + neighbor_j, roots);
                    if (root == neighbor_root) continue;
                    roots[root] = neighbor_root;
                    connectivities[neighbor_root] += connectivities[root];
                    connectivities[root] = 0;
                }
            }
        }
    }

    // Now we gonna print the root of area each point belongs to
    for (long i = 0; i < height; ++i) {
        for (long j = 0; j < width; ++j) {
            long index = i * width + j;
            printf("%3d", find_root(index, roots));
        }
        printf("\n");
    }

    // Now we gonna print the space of area each point belongs to
    for (long i = 0; i < height; ++i) {
        for (long j = 0; j < width; ++j) {
            long index = i * width + j;
            printf("%3d", connectivities[find_root(index, roots)]);
        }
        printf("\n");
    }

    free(connectivities);
    free(roots);
}

int main() {
    char mat[] = "YYYYYYYYYRGYRGYRGRGRGRGRGR"
                 "YYYYYYYYYRGYRGYRGRGRGRGRGR"
                 "YYYYYYYYRGYRGYRGRGRGRGRGRY";
    int width = 26;
    int height = 3;
    for (long i = 0; i < height; ++i) {
        for (long j = 0; j < width; ++j) {
            long index = i * width + j;
            printf("  %c", mat[index]);
        }
        printf("\n");
    }
    process(mat, width, height);
}

输出结果为:

  Y  Y  Y  Y  Y  Y  Y  Y  Y  R  G  Y  R  G  Y  R  G  R  G  R  G  R  G  R  G  R
  Y  Y  Y  Y  Y  Y  Y  Y  Y  R  G  Y  R  G  Y  R  G  R  G  R  G  R  G  R  G  R
  Y  Y  Y  Y  Y  Y  Y  Y  R  G  Y  R  G  Y  R  G  R  G  R  G  R  G  R  G  R  Y
  0  0  0  0  0  0  0  0  0  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  0  0  0  0  0  0  0  0  0  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
  0  0  0  0  0  0  0  0 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
 26 26 26 26 26 26 26 26 26  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2
 26 26 26 26 26 26 26 26 26  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2  2
 26 26 26 26 26 26 26 26  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1  1

基本上,它会将空间节省到连接数组中。此算法只需要扫描一次。