【问题标题】:PHP - how to tell if ALL adjacent elements in multidimensional array exist?PHP - 如何判断多维数组中的所有相邻元素是否存在?
【发布时间】:2013-09-27 23:54:35
【问题描述】:

这是我们在工作中遇到的一个愚蠢的小问题,我们中的一些人有不同的解决方案,我们想知道是否有更好的方法来解决。为了举例,我将其归结为非常简单的东西。

假设我们有一个多维数组,其中包含以下值。每个值都是它自己的元素,每一行都是一个数组。

0a00
000b
c000

在上面的 "array" 中,$array[0][1] 是 "a",$array[1][3] 是 "b",$array[2][0] 是 " C”。我们需要做的是,将与非数字值相邻的所有值加 1。因此,我们将值递增后的数组应如下面的数组所示。我们目前的解决方案是首先检查数组的所有 4 个“角”,递增相邻值,然后检查顶行和底行,然后检查第一列和最后一列,最后检查所有其他元素。每当我们碰到一个非数字元素时,我们都会将所有其他相邻的非数字元素加 1。这有点蹩脚/麻烦,我们知道必须有更好的方法。当您知道所有炸弹在哪里时,它几乎就是在反向构建一个炸弹扫地板。

1a21
222b
c111

【问题讨论】:

  • 我猜你输出结果或至少以某种方式查询它。为什么不在输出该特定字段时计算邻居的数量?这仍然是 O(n*n),但不会变得更快。
  • 啊,好的。我们认为必须有一种更有效的方法,它不涉及我们使用的嵌套循环。你是对的,我们输出它。实际的数组要复杂得多,但它们对一些数据进行建模,在实际问题中,我们所做的不仅仅是将每个相邻值加 1。
  • 您必须至少检查每个字段一次才能知道它是否是数字,因此至少这部分仍然是 O(width*height)。
  • 先检查边角,然后检查顶行和底行有什么好处?您肯定会遍历每个元素,并增加(最多)8 个相邻的值吗?
  • 除了懒惰的设计之外没有其他真正的好处,并且在将其排除时是合乎逻辑的(角落有一组相邻的元素,顶部/底部/左/右行/列也是如此)。没有真正的需要或好处。

标签: php arrays algorithm multidimensional-array


【解决方案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]++;
                        }
                    }
                }
            }
        }
    }

不确定这是否是最有效的方法,但它应该比你所拥有的更短。

【讨论】:

  • 我也非常喜欢这个解决方案。这与我们最终实现的接近(仅我们使用 isset 来检查元素是否存在而不是 max 检查)。
【解决方案2】:

我想到了这个简单的算法:

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 次。

【讨论】:

  • 谢谢,我真的很喜欢这个。
猜你喜欢
  • 1970-01-01
  • 2015-12-26
  • 2011-11-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多