【发布时间】:2011-05-15 12:45:27
【问题描述】:
我如何使用max()从数组中挑选出最高的 4 个值而不是 1 个?
【问题讨论】:
-
你不能用
max。max()返回参数值中数值最高的值。如果多个值可以被认为具有相同的大小,则将返回第一个列出的值。 -
正如戈登所说,你不能那样做。但是,您可以很聪明,一旦找到最大值 - 从数组中删除它并再次运行 max() 重复该过程直到您满意为止。
我如何使用max()从数组中挑选出最高的 4 个值而不是 1 个?
【问题讨论】:
max。 max() 返回参数值中数值最高的值。如果多个值可以被认为具有相同的大小,则将返回第一个列出的值。
您可以使用SplMaxHeap
function maxN(array $numbers, $n)
{
$maxHeap = new SplMaxHeap;
foreach($numbers as $number) {
$maxHeap->insert($number);
}
return iterator_to_array(
new LimitIterator($maxHeap, 0, $n)
);
}
用法(demo):
print_r( maxN( array(7,54,2,4,26,7,82,4,34), 4 ) );
【讨论】:
你可以试试这个:
$a = array(3,5,6,1,23,6,78,99);
asort($a);
var_dump(array_slice($a, -4));
HTH。
【讨论】:
O(n log n),而不是应该的O(n)。
O(n+4) 解决方案会是什么样子?
O(n+4),而是O(4n)(或只是O(n))。我添加了一个学术答案,但 Emil 的更好。
这将在 Θ(n) 时间内完成:
$a = $b = $c = $d = null;
foreach($array as $v) {
if(!isset($a) || $v > $a) {
$d = $c;
$c = $b;
$b = $a;
$a = $v;
}elseif(!isset($b) || $v > $b) {
$d = $c;
$c = $b;
$b = $v;
}elseif(!isset($c) || $v > $c) {
$d = $c;
$c = $v;
}elseif(!isset($d) || $v > $d) {
$d = $v;
}
}
$result = array($a, $b, $c, $d);
【讨论】:
asort 解决方案是用 PHP(在较低级别)实现的这一事实也有影响。
array_slice 变体在第一次运行后的每次后续运行后都优于此。另见codepad.viper-7.com/5yMTuu
fixed 应该说 return array($a,$b,$c,$d); 而不是 return array_slice($array, -4);。这可能对结果有影响。此外,在我的测试中,fixed 函数在小于 100,000 个项目的数组上速度较慢。
function maxs($ar, $count=4)
{
$res = array();
foreach ($ar as $v)
{
for ($i = 0;$i < $count;$i++)
{
if ($i >= count($res) || $v > $res[$i])
{
do
{
$tmp = $res[$i];
$res[$i] = $v;
$v = $tmp;
$i++;
}
while ($i < $count);
break;
}
}
}
return $res;
}
【讨论】:
Θ(4n) 中的解决方案,而不是O(4n log(4)),它概括了您的解决方案(但看起来更丑;))。
4 - 无论如何您已经删除了所有其他常量,那么为什么还要保留其中一个呢? ;-)
一个使用php预定义函数的简单方法。
<?php
$arr = array(6, 8, 3, 2, 7, 9);
rsort($arr);
$first = array_shift($arr);
$second = array_shift($arr);
$third = array_shift($arr);
echo $first; // print 9
echo $second; // print 8
echo $third; // print 7
?>
【讨论】:
在存储自身的同时,您可以在插入新项目后立即维护另一个数组,如果要插入的项目更大,请检查内部数组中的最大值插入此项目。在项目弹出期间反之亦然。从内部维护的数组中,您可以获得尽可能多的最大数。
【讨论】: