Futz测试arsort()依赖代码?

时间:2014-09-25 03:59:37

标签: php arrays

似乎一个庞大而复杂的代码库取决于arsort产生的顺序。在我深入了解50个课程中实际发生的事情之前 - 是否有一种简单的方法来重新调整具有相同价值的项目?

换句话说,如果输入是

['foo' => 3, 'bar' => 3, 'baz' => 3, 'this' => 2,  'that' => 2]

我想

['baz' => 3, 'bar' => 3, 'foo' => 3, 'this' => 2,  'that' => 2]

可能是一次运行,然后

['baz' => 3, 'bar' => 3, 'foo' => 3, 'that' => 2,  'this' => 2]

另一场随机游戏。

2 个答案:

答案 0 :(得分:1)

这样的事情怎么样? (未测试)

最差案例复杂性: O(k)

注意:写的是算法清晰度而不是PHP详细信息...

function shuffleInput( $data ) {
    // Separate into sets.
    $sets = [];
    foreach ( $data as $k => $v ) {
        $sets[$v][] = $k;
    }

    // Shuffle & Join.
    $data = [];
    foreach ( $sets as $v => &$set ) {
        shuffle( $set );
        foreach( $set as $k ) {
            $data[$k] = $v;
        }
    }
    return $data;
}

根据输入的大小,最好在第一个循环中取消设置$ data中的每个元素,而不是仅创建一个新数组。这适用于数据非常大且内存对您来说很宝贵 - 以及减少任何突然的峰值和内存使用量下降。

另外,如果您要继续随机播放相同的$数据,您可能希望将$ sets的制作分离到其他地方,或者至少允许开发人员传递/获取它作为副作用

答案 1 :(得分:0)

如果您不想处理shuffle,而是更愿意检查数组的所有排列,那么您可以执行以下操作:

$arr = array('foo' => 3, 'bar' => 3, 'baz' => 3, 'this' => 2,  'that' => 2);
$keys = array_keys($arr);
$indexes = range(0, count($arr) - 1);

pc_permute($indexes, $perms);

var_dump($perms);

function pc_permute($items, &$ret = array(), $perms = array( )) {
    if (empty($items)) { 
        $ret[] = $perms;
    }  else {
        for ($i = count($items) - 1; $i >= 0; --$i) {
             $newitems = $items;
             $newperms = $perms;
             list($foo) = array_splice($newitems, $i, 1);
             array_unshift($newperms, $foo);
             pc_permute($newitems, $ret, $newperms);
         }
    }
}

数组$ perms将给出索引的所有排列,可以从$ keys获取索引的键名,以及来自$ arr的键或索引值(使用array_slice):)

ps:但你应该明白 - 你在原始数组中拥有的元素越多,你会发现更多的排列。如果有n个元素那么就会有n!排列。对于n = 5,有120个排列。