似乎一个庞大而复杂的代码库取决于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]
另一场随机游戏。
答案 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个排列。