【问题标题】:Connected Areas in a Matrix矩阵中的连通区域
【发布时间】:2016-05-20 08:54:03
【问题描述】:

我有一个任务,我不知道我应该如何解决这个问题。我有一个想法,但我不知道这是否是解决它的最佳方法。 这是任务: 给定的是“1”和“0”的二维矩阵。找到连接区域的确切数量。一个连接区域由“1”组成,这些“1”是其他“1”的邻居(水平、垂直或对角线都算!)。如果一个“1”被“0”包围,这个“1”本身也是一个连通区域。 这里有 4 个例子:

矩阵:
0 0 1 0
1 0 1 0
0 1 0 0
1 1 1 1

解决方案:1(我们可以将所有 1 连接在一起)

1 0 0 1
0 0 0 0
0 1 1 0
1 0 0 1

解决方案3(第一行的1都算一个区域,其他1可以连接)

1 0 0 1 1
0 0 1 0 0
0 0 0 0 0
1 1 1 1 1
0 0 0 0 0

解决方案:3(左上角一个区域,1的右上角一个区域,第三个区域是第4列)

0 0 1 0 0 1 0 0
1 0 0 0 0 0 0 1
0 0 1 0 0 1 0 1
0 1 0 0 0 1 0 0
1 0 0 0 0 0 0 0
0 0 1 1 0 1 1 0
1 0 1 1 0 1 1 0
0 0 0 0 0 0 0 0

解决方案:9

我的想法是将数字放入二维数组并将其用作坐标系。我会搜索第一个“1”,将其设置为 0,然后在其位置寻找其他“1”(x +/- 1;y +/- 1)。如果还有另一个 1,我会将其替换为 0 并在此周围搜索,依此类推。如果周围没有“1”,我就知道我找到了一个完整的区域。之后我会遍历数组并做同样的事情,直到我的数组中只有 0 和连接区域的数量。

你认为这是最好的方法吗?或者你能告诉我一个更好的方法来解决这个问题吗?

【问题讨论】:

  • 树结构比矩阵更适合“环视”
  • 你是什么意思?

标签: php arrays matrix


【解决方案1】:

这是我的解决方案。 $_POST['input'] 是来自 html 公式的发布数据的示例。这个解决方案是我最好的主意。你有别的想法吗?

$_POST['input'] =' 
    4
    4
    0 0 1 0
    1 0 1 0
    0 1 0 0
    1 1 1 1
    4
    1 0 0 1
    0 0 0 0
    0 1 1 0
    1 0 0 1
    5
    1 0 0 1 1
    0 0 1 0 0
    0 0 0 0 0
    1 1 1 1 1
    0 0 0 0 0
    8
    0 0 1 0 0 1 0 0
    1 0 0 0 0 0 0 1
    0 0 1 0 0 1 0 1
    0 1 0 0 0 1 0 0
    1 0 0 0 0 0 0 0
    0 0 1 1 0 1 1 0
    1 0 1 1 0 1 1 0
    0 0 0 0 0 0 0 0
';

if (isset($_POST['input'])) {

    $allMatrizes = convertToArray($_POST['input']);

    foreach ($allMatrizes as $matrix) {
        $matrixSize = count($matrix);
        $amountOfConnectedAreas = searchConnectedAreas($matrix, $matrixSize);
        echo $amountOfConnectedAreas . '<br/>';
    }
}


function convertToArray($input) {
    $input = preg_replace('/[^0-9]/', '', $input);
    $index = 1;
    $count = strlen($input);
    $allMatrizes = [];
    while ($index < $count) {
        $matrixSize = $input[$index];
        $matrix = [];
        $line = [];
        for ($i = 0; $i < $matrixSize * $matrixSize; $i++) {
            if ($i % $matrixSize == 0 && $i != 0) {
                array_push($matrix, $line);
                $line = [];
                array_push($line, $input[$i + $index + 1]);
            } else {
                array_push($line, $input[$i + $index + 1]);
            }
        }
        array_push($matrix, $line);
        $index += $i + 1;
        array_push($allMatrizes, $matrix);
    }
    return $allMatrizes;
}

function searchConnectedAreas($matrix, $matrixSize) {
    $x = 0;
    $y = 0;
    // find the first "1"
    $found = false;
    $connectedAreas = 0;
    while ($y < $matrixSize && $x < $matrixSize) {
        $element = $matrix[$y][$x];
        if ($element == 1) {
            $connectedAreas += 1;
            $matrix = eliminateConnectedArea($matrix, $matrixSize, $x, $y);
        }

        // go on and search for next 1
        $x += 1;
        if ($x == $matrixSize) {
            $x = 0;
            $y  += 1;
        }
    }
    return $connectedAreas;
}

function eliminateConnectedArea($matrix, $matrixSize, $x, $y) {
    // set element to 0
    $matrix[$y][$x] = '0';
    // search around for other 1 and call self
    $newX = $x - 1;
    $newY = $y -1;
    while ($newX <= $x +1 && $newY < $matrixSize && $newY <= $y +1) {
        if ($newX >= 0 && $newY >= 0) {
            $element = $matrix[$newY][$newX];
            if ($element == 1) {
                $matrix = eliminateConnectedArea($matrix, $matrixSize, $newX, $newY);
            }
        }

        $newX += 1;
        if ($newX == $matrixSize || $newX > $x +1) {
            $newX = $x - 1;
            $newY  += 1;
        }
    }
    return $matrix;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-19
    • 2015-12-20
    相关资源
    最近更新 更多