2014-09-25 69 views
1

似乎一個龐大而複雜的代碼庫取決於arsort生成的順序。在我深入瞭解50個班級中實際發生的情況之前 - 是否有一種簡單的方法來調換具有相同值的項目?Futz測試arsort()相關的代碼?

換句話說,如果輸入的是

['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] 

另一個隨機運行。

+1

那些是重複的鍵 – Ghost 2014-09-25 04:04:40

+0

我第二@Ghost - 洗牌數組,你應該使用Fisher Yates算法:http://stackoverflow.com/questions/3169805/how-can-i-randomize-an-array- in-php-by-provide-a-seed-and-get-the-order – Centril 2014-09-25 04:05:58

+0

@Ghost對不起,我試着舉一個簡單的例子。固定。 – chx 2014-09-25 04:10:06

回答

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的製作分離出來,或者至少讓開發者通過/將其作爲副作用。

+0

在shuffle之後,您可以執行'call_user_func_array('array_merge',$ set)'而不是foreach。 – chx 2014-09-25 08:15:11

+0

不,你不能,因爲$ set是「type」array [index => $ k]而不是[$ k => $ v],這是你需要的。此外,如果你想調用array_merge,你可以做到這一點,沒有多餘的思考。我相信我是最有效的方式... 可能的改進:使C調用foreach所做的 - 即:array_add($ dest,$ keys,$ value_for_all); 另請參見:爲foreach中的array_pop提供一種方法,並訪問該鍵以便在到達重置行時使$ data已爲空。 – Centril 2014-09-25 08:33:57

0

如果你不想對付洗牌,而是更願意檢查數組的所有排列,那麼你可以做這樣的事情:

$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); 
     } 
    } 
} 

陣列$燙髮會給索引的所有排列,按索引鍵的名稱,你可以從$鍵和價值按鍵或索引(使用array_slice)從$ ARR :)

PS:但你應該明白 - 你有更多的元素,你在原有的數組,你會更多的排列找。如果有n個元素,那麼會有n!排列。對於n = 5,有120個排列。

+0

哎喲,這是一個有趣的想法,但由於O(n!)有點不可用^^ – Centril 2014-09-25 04:47:10

+0

@Centril它取決於.. – Cheery 2014-09-25 04:52:15