计数用PHP排序

时间:2011-12-30 16:12:41

标签: php algorithm sorting data-structures

在PHP项目中,我有一些数据,我想使用线性时间排序,简单的计数排序:

$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$count = array();
foreach ($ar as $v)
    $count[$v]++;
$sorted = array();    
foreach ($count as $v => $c)
    for ($i = 0; $i < $c; $i++)
        $sorted[] = $v;

问题是以上显然不起作用。 php数组的工作方式更像是散列映射而不是数组。可以通过在最终循环之前插入ksort($count)来使代码工作,但ksortO(nlogn)中运行会破坏整个点。

有没有办法在PHP中进行线性时间排序?也许使用一些参数array(),或者一些完全不同的结构?

5 个答案:

答案 0 :(得分:3)

您没有正确关注algorithm。这是O(n)。

$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$count = array();
foreach ($ar as $v) {
    $count[$v] = isset($count[$v]) ? $count[$v] + 1 : 1;
}
$sorted = array();
$min = min($ar);
$max = max($ar);
for ($i=$min; $i<=$max; $i++) {
    if (isset($count[$i])) {
        for ($j=0; $j<$count[$i]; $j++) {
            $sorted[] = $i;
        }
    }
}

另外,请参阅array_count_values(),或者计算计数循环内的最小值和最大值。

答案 1 :(得分:0)

如果我理解你的问题并正确评论,那么只使用sort($ count)就可以了吗?

$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$sorted = $ar;
sort($sorted);
var_dump($ar);
var_dump($sorted);

结果:

array(7,2,0,3,8,0,12,7,6,7);
array(0,0,2,3,6,7,7,7,8,12);

但我想知道foreach($ ar as $ v)$ count [$ v] ++; ......真的没有意义......

答案 2 :(得分:0)

要在自己的变量($ar)中获取已排序的$sorted,这非常简单:

$sorted = $ar;
sort($sorted);

这让我觉得你的问题和评论没有全面展现。

编辑现在,在你澄清了你想要实现一个特定的算法之后(你实际上已经得到了一个答案,显示了一些错误的实现它的错误点),我认为这是值得的关注你问题的另一个方面:

您正在比较两种(理论)算法的复杂性,但您不考虑算法的实现方式。

PHP sort() - 即使基于“坏”快速排序,也会超过您自己的PHP用户代码实现其他算法的数字

您刚刚在这里比较了错误的参数。当您将内置PHP函数与用户代码中的某些函数进行比较时,函数的复杂性并不多。

答案 3 :(得分:0)

在代码中添加一些注释,向您展示为什么这样做不符合您认为应该做的事情。

$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);

$count = array();
foreach ($ar as $v) {
    // add each number in $ar to $count.
    // the first number in $ar is 7, so 7 will be the first number in $count.
    // because 7 is in $ar 3 times, $count[7] == 3.
    $count[$v]++;
}

// the output of print_r will be very revealing:
print_r($count);
/*Array
(
    [7] => 3
    [2] => 1
    [0] => 2
    [3] => 1
    [8] => 1
    [12] => 1
    [6] => 1
)*/

$sorted = array();    
foreach ($count as $v => $c) {
    // the first entry: $count[7] == 3
    // so add 7 to $sorted 3 times.
    // the second entry: $count[2] == 1
    // so add 2 to $sorted 1 time.
    // etc.
    for ($i = 0; $i < $c; $i++) {
        $sorted[] = $v;
    }
}

这只是根据数字在第一个数组中的位置将数字组合在一起。

答案 4 :(得分:0)

批准的答案是错误的。正确的:

$ar = array(7, 2, 0, 3, 8, 0, 12, 7, 6, 7);
$count = array();
foreach ($ar as $v) {
    $count[$v] = isset($count[$v]) ? $count[$v] + 1 : 1;
}
$sorted = array();
$min = min($ar);
$max = max($ar);
for ($i=$min; $i  <=   $max; $i++) {
    if (isset($count[$i])) {
        for ($j=0; $j<$count[$i]; $j++) {
            $sorted[] = $i;
        }
    }
}