矩阵中的连通区域

时间:2016-05-20 08:54:03

标签: php arrays matrix

我有一项任务,我不确定如何解决问题。我有一个idead,但我不知道它是否是解决它的最佳方法。 这是任务: 给定是" 1"的二维矩阵。和" 0"。找到连接区域的确切数量。连接区域包括" 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和连接区域的数量。

你认为这是最好的方法还是你能指出我如何才能更好地解决这个问题?

1 个答案:

答案 0 :(得分:0)

这是我的解决方案。 $ _POST ['输入']是来自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;
}