【问题标题】:Quick Way to Find the Largest Array in a Multidimensional Array?在多维数组中找到最大数组的快速方法?
【发布时间】:2014-03-18 16:21:55
【问题描述】:

情况:我有一个包含可变数量元素的多维数组。例如

array(N) {
    0 => array(3) { ... },
    1 => array(8) { ... },
    2 => array(1) { ... },
    ...
    M => array(12) { ... },
    ...
    N-1 => array(7) { ... }
}

我想找出这个子数组中元素的最大数量(在上面的例子中,它是 12)。一个简单的解决方案是 O(N) 线性搜索。

<?php
function max_length($2d_array) {
    $max = 0;
    foreach($2d_array as $child) {
        if(count($child) > $max) {
            $max = count($child);
        }
    }
    return $max;
}

但是,我不禁想知道是否有一些巧妙的技巧可以优化此查找。所以我的问题是两部分的(尽管任何一部分的答案都可以解决):

  • 是否有一种算法可以比 O(N) 更快地执行此搜索,而无需特殊要求(预排序等)?
  • 是否有一个不起眼的 PHP 函数将在本机代码而不是我的用户级 PHP 脚本中执行此搜索?

【问题讨论】:

    标签: php arrays computer-science


    【解决方案1】:

    你可以使用这个:https://www.php.net/manual/ro/function.max.php

    $test = array(
               array('G', 'M', 2, 2),
               array(1, 2222, 3)
             );
     $arr = max($test);
    

    // 输出 ->

    array(4) {
      [0]=>
      string(1) "G"
      [1]=>
      string(1) "M"
      [2]=>
      int(2)
      [3]=>
      int(2)
    }
    

    【讨论】:

    • 对于max(),这是一个整洁、出乎意料但记录在案的行为。
    【解决方案2】:

    不确定性能,但我认为以下应该可行:

    $count = array_map('count', $input_arr);
    $min = array_keys($count , max($count))[0];
    $largest_arr = $input_arr[$min];
    

    甚至:

    $counts = array_map('count', $input_arr);
    $key = array_flip($counts)[max($counts)];
    $largest_arr = $input_arr[$key];
    

    【讨论】:

    • @Scott:你看到第二个解决方案了吗? (答案的第一部分)
    • gist.github.com/sarciszewski/9076834 我看到了,直到现在才进行基准测试。
    • @Scott:这些是一样的。两个要点之间的唯一区别在于$key = array_flip($counts)[max($counts)]; 行。我只是将其缩短为包含在一行中。我说的是这个:$min = array_keys($count , max($count))[0];
    • @Scott:嗯,你必须做超过 1000 次才能获得一些稳定的结果。这是我的版本(100000 迭代):gist.github.com/amalmurali47/9077238
    【解决方案3】:

    1) 按元素大小对多维数组进行排序:
    选择在 O(n logn) 最坏情况下运行的算法,例如堆排序 (comparison of sorting algorithms)。

    2) 选择最后一个元素。
    这在 O(1) 中运行

    因此,如果您自己实现排序算法并假设获取数组长度是 O(1) 并且不是线性的(每次询问长度时都不计算),您可以在 O(n logn) 中完成

    由于我没有使用它,因此我无法评论任何为您执行此操作的 PHP 方法。

    【讨论】:

    • 严格来说,N log N 比 N 差:1000 * lg(1000) 刚好低于 10,000。我很感激你的努力
    • 如果有一个排序算法的性能比 O(n) 好,那么这就是你的解决方案。我用 O(n logn) 发布了这个答案,因为这是目前比较排序算法的最佳界限。所以它不能比这更快,除非你找到一种方法来对它进行非比较排序而不将数组重新编码为数字表示(这对我来说似乎不可能)。
    • 好吧,如果对数据进行排序,得到 O(1) 是微不足道的;这就是为什么我指定“不需要特殊要求(预先排序等)”。排序是昂贵的。不过,感谢您的回答;如果我需要对数据进行从最短到最长的排序,堆排序可能会有很大帮助;)
    【解决方案4】:

    只是为了好玩:

    array_multisort($result = array_map('count', $array), SORT_DESC);
    echo $result[0];
    

    【讨论】:

    • 嘿。简单的解决方案:结果 44 在 0.049926996231079 秒内计算。堆栈溢出:结果 44 在 0.13289713859558 秒内计算。
    • @Scott:我不知道那是什么意思。此外,array_multisort 返回布尔值,所以没有 array_shift
    • 我正在对其进行基准测试。它花费的时间是天真的方法的 3 倍。您可以在函数调用上下文中使用return array_shift($result);
    • 是的,我的做法是“只是为了好玩”:0
    • 是的,这是一个有趣的解决方案。但为了公平起见,我对它进行了基准测试。 ;)
    【解决方案5】:
    $max = 0;
    foreach($array as $obj)
    {
        if($obj->dnum > $max)
        {
            $max = $obj->dnum;
        }
    }
    

    $numbers = array();
    foreach($array as $obj)
    {
        $numbers[] = $obj->dnum;
    }
    $max = max($numbers);
    

    或者...

    阅读该文章的更多信息 - Get the maximum value from an element in a multidimensional array?How to find the largest array from a multi dimensional array

    【讨论】:

    • 很遗憾,我们没有要比较的 $obj->dnum,所以这个解决方案行不通。
    【解决方案6】:

    这个怎么样:

    function accmp(&$a, &$b) {  return count($a)<count($b)?-1:1; }
    $arraylist=array(array(1,2),array(1,2,3),array(1),array(1,2,3,4,5,6),array(1,2,3,4),array(2,3,4));
    echo 'original arraylist:<br>'; print_r($arraylist); echo '<br>';
    usort($arraylist,'accmp');
    echo 'largest array::<br>'; print_r(end($arraylist)); echo '<br>';
    echo 'largest size = '.count(end($arraylist))
    

    只需按count(array-element)的升序对arraylist中的array-element进行排序并取最后一个元素。

    【讨论】:

      猜你喜欢
      • 2014-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多