根据PHP值查找Max键

时间:2012-10-17 01:08:12

标签: php arrays loops

我正在尝试根据另一个值找到PHP数组的最高键。

$values = array(0,0,50,100,200,400,800);

如果我说我的值为125,它应该返回3.如果我有400到799之间的任何值,它应该返回5.

$output = -1;
$input = 436;
$length = count($values);
for($i=1;$i<=$length;$i++){
    if($values[$i]<=$input) { $output++; }
}
// Returns 5

我可以遍历数组,但是有100个值,这会使页面减慢很多,因为每个用户每页加载使用约20次。我有什么特殊功能吗?或者我将不得不联系阵列?

数组始终处于有序状态且永不改变。

2 个答案:

答案 0 :(得分:1)

很抱歉,但AFAIK你真的必须绕过这个低谷。

Iff 对数组进行排序,您可以找到第一个更高的索引,然后只添加其余的索引。


编辑:以下是我用来进行基准测试的代码:

set_time_limit(0);

$a = array(0,0,50,100,200,400,800);
$a = array_merge(range(0, 100000), $a);

sort(a); // we need this since array_merge will not maintain the sequence

$result = array
(
    'testWithForeach' => 0,
    'testWithArrayFlip' => 0,
    'testWithArraySearch' => 0,
);

foreach (range(0, 1000, 10) as $n) // search values $n to try
{
    for ($i = 0; $i < 10; ++$i) // how many times to run each test
    {
        foreach (array_keys($result) as $test) // divide the CPU usage fairly (inner-most loop)
        {
            $start = microtime(true); call_user_func($test, $a, $n); $result[$test] += (microtime(true) - $start);
        }
    }
}

asort($result);

echo '<pre>';
print_r($result);
echo '</pre>';

function testWithForeach($a, $n)
{
    foreach ($a as $key => $value)
    {
        if ($value >= $n)
        {
            $result = $key; break;
        }
    }

    return $result;
}

function testWithArrayFlip($a, $n)
{
    $a[] = $n; sort($a); $a = array_flip($a); return ($a[$n] - 1);
}

function testWithArraySearch($a, $n)
{
    $a[] = $n; sort($a); return (array_search($n, $a) - 1);
}

所有方法都在类似的条件下运行,并分散在CPU时间内。

我测试了从0到1000的所有$n值,使用10作为步骤(总共100个)。

每个$n /方法组合运行了10次,我得到的结果是:

Array
(
    [testWithForeach] => 19.338931560516
    [testWithArraySearch] => 96.209128856659
    [testWithArrayFlip] => 133.85276961327
)

我尽量保持公平,实际的运行时间可能因$n和其他条件而异。

答案 1 :(得分:1)

您可以使用array_flip()执行此操作。

[ghoti@pc ~]$ php -r '$n=150; $a=array(0,0,50,100,200,400,800); $a[]=$n; sort($a); $f=array_flip($a); print $f[$n]-1 . "\n";'
3
[ghoti@pc ~]$ php -r '$n=401; $a=array(0,0,50,100,200,400,800); $a[]=$n; sort($a); $f=array_flip($a); print $f[$n]-1 . "\n";'
5
[ghoti@pc ~]$ php -r '$n=200; $a=array(0,0,50,100,200,400,800); $a[]=$n; sort($a); $f=array_flip($a); print $f[$n]-1 . "\n";'
4
[ghoti@pc ~]$ php -r '$n=0; $a=array(0,0,50,100,200,400,800); $a[]=$n; sort($a); $f=array_flip($a); print $f[$n]-1 . "\n";'
1

这是如何运作的?

让我们把它分解。

  • $n=0;我们的号码。
  • $a=array(0,0,50,100,200,400,800);我们的阵列。
  • $a[]=$n;我们将我们的号码添加到数组......
  • sort($a);对事物进行排序,将我们的号码放在正确的位置......
  • $f=array_flip($a);然后我们用索引交换价值
  • print $f[$n]-1并在我们添加的项目之前返回项目的值(以前是索引)。

如果$ a包含多个相同数字的条目,可能会产生混淆,例如示例中的0。如果发生这种情况,您可能需要调整调整(在我的示例中为-1),因为索引只能在数组中出现一次。 (例如,如果0出现三次,则需要使用-2调整结果。此调整可以添加额外的代码,但我相信您可以自己计算出这一部分。:)

这可以避免循环,但请注意$n=0