7

Situation: I have a multidimensional array with a variable number of elements. e.g.

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

And I would like to find the maximum number of elements in this sub-array (in the example above, it would be 12). A straightforward solution would be an O(N) linear search.

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

However, I can't help but wonder if there's some clever trick to optimize this lookup. So my question is a two-parter (though an answer to either part would solve it):

  • Is there an algorithm that performs this search faster than O(N) without requiring special requirements (pre-sorted, etc)?
  • Is there an obscure PHP function somewhere that will perform this search in native code rather than my userland PHP script?
Scott Arciszewski
  • 33,610
  • 16
  • 89
  • 206

6 Answers6

7

You can use this : https://www.php.net/manual/ro/function.max.php

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

// output ->

array(4) {
  [0]=>
  string(1) "G"
  [1]=>
  string(1) "M"
  [2]=>
  int(2)
  [3]=>
  int(2)
}
Ravi B
  • 1,574
  • 2
  • 14
  • 31
Marian
  • 86
  • 1
  • 2
4

Not sure about the performance, but I think the following should work:

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

Or even:

$counts = array_map('count', $input_arr);
$key = array_flip($counts)[max($counts)];
$largest_arr = $input_arr[$key];
Amal Murali
  • 75,622
  • 18
  • 128
  • 150
  • @Scott: Did you see the second solution? (the first part of the answer) – Amal Murali Feb 18 '14 at 18:27
  • https://gist.github.com/sarciszewski/9076834 I saw it, hadn't benchmarked it until just now. – Scott Arciszewski Feb 18 '14 at 18:31
  • @Scott: Those are the same. The only difference between both the gists are in the line `$key = array_flip($counts)[max($counts)];`. I just shortened it to include in a single line. The one I'm talking about is this one: `$min = array_keys($count , max($count))[0];` – Amal Murali Feb 18 '14 at 18:40
  • @Scott: Well, you have to do it for more than 1000 to get some stable results. Here's my version (with `100000` iterations): https://gist.github.com/amalmurali47/9077238 – Amal Murali Feb 18 '14 at 18:51
  • 1
    let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/47789/discussion-between-amal-murali-and-scott) – Amal Murali Feb 18 '14 at 18:51
2

1) Sort the multi-dim array by the element sizes:
Choose an algorithm that runs in O(n logn) worst case, e.g. Heap Sort (comparison of sorting algorithms).

2) Choose the last element.
This runs in O(1)

So if you implement the sorting algorithm yourself and assuming that fetching the array length is O(1) and not linear (no counting every time you ask for the length), you can do it in O(n logn)

I can't comment on any PHP methods which do this for you since I'm not using it.

runDOSrun
  • 10,359
  • 7
  • 47
  • 57
  • Strictly speaking, N log N is worse than N: 1000 * lg(1000) is just below 10,000. I appreciate the effort though – Scott Arciszewski Feb 18 '14 at 18:17
  • 1
    If there is a sorting algorithm that performs better than O(n), then that's your solution. I posted this answer with O(n logn) since this is currently the best bound known for comparing sorting algorithms. So it can't be faster than this unless you find a way to sort it non-comparingly without reencoding the array into a numeric representation (which seems impossible to me). – runDOSrun Feb 18 '14 at 18:24
  • Well, if the data is sorted, getting O(1) is trivial; that's why I specified "without requiring special requirements (pre-sorted, etc)". Sorting is expensive. Thanks for your answer, though; if I had a requirement to sort the data shortest-to-longest, heap-sort would probably help significantly ;) – Scott Arciszewski Feb 18 '14 at 18:26
1

Just for fun:

array_multisort($result = array_map('count', $array), SORT_DESC);
echo $result[0];
AbraCadaver
  • 78,200
  • 7
  • 66
  • 87
0
$max = 0;
foreach($array as $obj)
{
    if($obj->dnum > $max)
    {
        $max = $obj->dnum;
    }
}

or

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

or ...

Read more in that article - Get the maximum value from an element in a multidimensional array? or How to find the largest array from a multi dimensional array

Community
  • 1
  • 1
TN888
  • 7,659
  • 9
  • 48
  • 84
0

How about this:

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))

Just sort array-element in arraylist in ascending order of count(array-element) and take last element.

Scott Chu
  • 972
  • 14
  • 26