Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在我的算法中,在0和1的数组中查找1的最大连通区域的大小的缺陷在哪里?_C#_Algorithm - Fatal编程技术网

C# 在我的算法中,在0和1的数组中查找1的最大连通区域的大小的缺陷在哪里?

C# 在我的算法中,在0和1的数组中查找1的最大连通区域的大小的缺陷在哪里?,c#,algorithm,C#,Algorithm,例如,如果数组是 1 1 0 0 0 1 1 0 0 0 1 0 1 0 0 0 那么答案是5 我有一个助手函数 // Returns the size of the region of 1s containing the point (x0, y0). // For example, if mat = 0 0 1 // 1 0 0 // 1 1 1 // then max_connected_regio

例如,如果数组是

1 1 0 0
0 1 1 0
0 0 1 0
1 0 0 0
那么答案是
5

我有一个助手函数

// Returns the size of the region of 1s containing the point (x0, y0). 
// For example, if mat = 0 0 1
//                       1 0 0
//                       1 1 1
// then max_connected_region(0,0,mat) = 0, 
//      max_connected_region(2,0,mat) = 1,
//  and max_connected_region(0,1,mat) = 4
static int max_connected_region(int x0, int y0, int[,] mat)
{  
    if(mat[x0,y0] == 0)
        return 0;
    var surroundings = (new int[][] {
        new int[] { x0 - 1, y0 }, new int[] {x0 + 1, y0 }, 
        new int[] { x0 - 1, y0 + 1}, new int[] { x0, y0 + 1 }, new int[] {x0 + 1, y0 + 1},
        new int[] { x0 - 1, y0 - 1}, new int[] { x0, y0 - 1 }, new int[] {x0 + 1, y0 - 1} }
     ).Where(pair => pair[0] >= 0 && pair[0] < mat.GetLength(0) && pair[1] >= 0 && pair[1] < mat.GetLength(1));
    int count = 1;
    foreach(var pair in surroundings)
        count += max_connected_region(pair[0], pair[1], mat);
    mat[x0,y0] = 0;
    return count;
}
这个过程在测试用例中给了我一个超时或越界,我不知道为什么。

因为,您的算法正在重新访问已经检查过的数组元素,将其放入一个无休止的循环中

实际上,您有一个程序语句似乎试图避免这种情况,但您在递归调用之后执行它。因此,它没有任何有用的效果。如果您只是将其移动到执行递归调用的循环之前,那么您的算法将工作:

static int max_connected_region(int x0, int y0, int[,] mat)
{
    if (mat[x0, y0] == 0)
        return 0;
    var surroundings = (new int[][] {
        new int[] { x0 - 1, y0 }, new int[] {x0 + 1, y0 }, 
        new int[] { x0 - 1, y0 + 1}, new int[] { x0, y0 + 1 }, new int[] {x0 + 1, y0 + 1},
        new int[] { x0 - 1, y0 - 1}, new int[] { x0, y0 - 1 }, new int[] {x0 + 1, y0 - 1} }
     ).Where(pair => pair[0] >= 0 && pair[0] < mat.GetLength(0) && pair[1] >= 0 && pair[1] < mat.GetLength(1));
    int count = 1;
    mat[x0, y0] = 0;
    foreach (var pair in surroundings)
        count += max_connected_region(pair[0], pair[1], mat);
    return count;
}

它是怎样的
5
?你试图解释的逻辑是什么apply@un-幸运的是,它是
1
s中最大的岛屿。你能解释一下你的算法应该如何工作吗?啊,我明白了。。在我看来像是无界递归。你检查一个单元的邻域,然后递归地检查它们的邻域,其中一个当然是原始单元。这并不是真正回答你的问题,但更好的方法是构建一个图,其中一个节点是一行中
1
s的连续单元。如果两个节点位于连续的行上,并且有一个单元格属于同一列,则这两个节点是连接的。边的权重是两个节点中的单元数。所以这个图实际上是一个树的集合,你需要找到一个边和最大的树。
static int max_connected_region(int x0, int y0, int[,] mat)
{
    if (mat[x0, y0] == 0)
        return 0;
    var surroundings = (new int[][] {
        new int[] { x0 - 1, y0 }, new int[] {x0 + 1, y0 }, 
        new int[] { x0 - 1, y0 + 1}, new int[] { x0, y0 + 1 }, new int[] {x0 + 1, y0 + 1},
        new int[] { x0 - 1, y0 - 1}, new int[] { x0, y0 - 1 }, new int[] {x0 + 1, y0 - 1} }
     ).Where(pair => pair[0] >= 0 && pair[0] < mat.GetLength(0) && pair[1] >= 0 && pair[1] < mat.GetLength(1));
    int count = 1;
    mat[x0, y0] = 0;
    foreach (var pair in surroundings)
        count += max_connected_region(pair[0], pair[1], mat);
    return count;
}
static int max_connected_region2(int x0, int y0, int[,] mat)
{
    return max_connected_region2_impl(x0, y0, (int[,])mat.Clone());
}

static int max_connected_region2_impl(int x0, int y0, int[,] mat)
{
    if (mat[x0, y0] == 0)
        return 0;

    int count = 1;

    mat[x0, y0] = 0;
    for (int i = 0; i < adjacentCells.Length; i++)
    {
        int[] pair = adjacentCells[i];
        int x1 = pair[0] + x0, y1 = pair[1] + y0;

        if (x1 >= 0 && x1 < mat.GetLength(0) && y1 >= 0 && y1 < mat.GetLength(1))
        {
            count += max_connected_region2_impl(x1, y1, mat);
        }
    }
    return count;
}

private static readonly int[][] adjacentCells =
{
    new [] { -1, 0 }, new [] { 1, 0 }, new [] { -1, 1 }, new [] {0, 1 },
    new [] { 1, 1 }, new [] { -1, -1}, new [] { 0, -1 }, new [] { 1, -1 }
};