2

これは私たちが仕事で抱えていたばかげた小さな問題であり、私たちの何人かは異なる解決策を持っており、それを行うためのより良い方法があるかどうか疑問に思っています. 例として、非常に単純なものに要約します。

以下の値を含む多次元配列があるとします。各値は独自の要素であり、各行は配列です。

0a00
000b
c000

上記の「配列」では、$array[0][1] は「a」、$array[1][3] は「b」、$array[2][0] は「c」になります。必要なことは、数値以外の値に隣接するすべての値を 1 ずつインクリメントすることです。したがって、値をインクリメントした後の配列は、以下の配列のようになります。現在の解決策は、最初に配列の 4 つの「コーナー」をすべてチェックし、隣接する値をインクリメントしてから、一番上の行と一番下の行をチェックし、次に最初と最後の列をチェックし、最後に他のすべての要素をチェックすることです。非数値要素にヒットするたびに、隣接する他のすべての非数値要素を 1 ずつインクリメントします。すべての爆弾がどこにあるかを知っている場合、それはほとんど逆に爆弾掃除ボードを構築しています.

1a21
222b
c111

4

2 に答える 2

1

私はこの単純なアルゴリズムを念頭に置いています:

function getNeighborsCount($rgData, $iX, $iY)
{
   if(ord($rgData[$iX][$iY])>=ord('a') && ord($rgData[$iX][$iY])<=ord('z'))
   {
      return null;
   }
   $iResult = 0;
   for($i=$iX-1; $i<=$iX+1; $i++)
   {
      for($j=$iY-1; $j<=$iY+1; $j++)
      {
         if(isset($rgData[$i][$j]) && 
            ord($rgData[$i][$j])>=ord('a') && 
            ord($rgData[$i][$j])<=ord('z'))
         {
            $iResult++;
         }
      }
   }
   return $iResult;
}

-次に、配列全体に適用します。

$rgData = [
   str_split('0a00'),
   str_split('000b'),
   str_split('c000')
];

for($i=0; $i<count($rgData); $i++)
{
   for($j=0; $j<count($rgData[$i]); $j++)
   {
      if($iCount = getNeighborsCount($rgData, $i, $j))
      {
         $rgData[$i][$j]=$iCount;
      }
   }
}

-これは次のようになります

echo(join(PHP_EOL, array_map(function($rgStr)
{
   return join('', $rgStr);
}, $rgData)));

に:

1a21
222b
c111

さて、複雑さについて。N要素がある場合は、O(9N)関数内の要素ごとに 9 回反復しているためです。

于 2013-09-23T07:11:18.740 に答える
1

面白い小さなパズル。次のことを試してください。


    $arr = array(
        array(0, 'a', 0, 0),
        array(0, 0, 0, 'b'),
        array('c', 0, 0, 0),
    );

    $max_i = count($arr);
    $max_j = count($arr[0]);
    for ($i = 0; $i < $max_i; $i++) {
        for ($j = 0; $j < $max_j; $j++) {
            if (!is_int($arr[$i][$j])) {
                for ($_i = $i - 1; $_i <= $i + 1; $_i++) {
                    for ($_j = $j - 1; $_j <= $j + 1; $_j++) {
                        if (($_i == $i && $_j == $j) || $_i < 0 || $_i >= $max_i || $_j < 0 || $_j >= $max_j) {
                            continue;
                        }
                        if (is_int($arr[$_i][$_j])) {
                            $arr[$_i][$_j]++;
                        }
                    }
                }
            }
        }
    }

これが最も効率的な方法かどうかはわかりませんが、現在の方法よりも短くする必要があります。

于 2013-09-23T07:10:41.697 に答える