2 回答

TA貢獻1865條經驗 獲得超7個贊
您可以使用最小堆或最小優先級隊列(在 PHP 中略有不同)。當該堆具有 k 個元素時,當您找到的條目的分數高于堆中該最小分數時,請交換堆的頂部元素。然后,您最終將獲得k個頂部條目,得分最低的位于頂部。因此,作為最后一步,您將從堆中提取條目并反轉其順序。
以下是使用SplPriorityQueue的外觀。請注意,此結構將最大優先級值放在頂部,因此我們將為其提供負分數,以便在堆/隊列頂部獲得最低分數:
function getTop($input, $k) {
$q = new SplPriorityQueue();
$q->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
foreach ($input as $entry) {
if ($q->count() < $k) {
$q->insert($entry, -$entry["score"]); // negate score to get lower scores first
} else if ($entry["score"] > -$q->top() ) { // better score than least in queue? Exchange
$q->extract();
$q->insert($entry, -$entry["score"]);
}
}
$q->setExtractFlags(SplPriorityQueue::EXTR_DATA);
return array_reverse(iterator_to_array($q));
}
下面是一些示例輸入數據以及如何調用上述函數:
$input = [
["user" => "a", "score" => 17],
["user" => "b", "score" => 3],
["user" => "c", "score" => 10],
["user" => "d", "score" => 11],
["user" => "e", "score" => 5],
["user" => "f", "score" => 19],
["user" => "g", "score" => 7],
["user" => "h", "score" => 2],
["user" => "i", "score" => 18],
["user" => "j", "score" => 12],
["user" => "k", "score" => 10],
["user" => "l", "score" => 6],
["user" => "m", "score" => 9],
["user" => "n", "score" => 15],
];
$top = getTop($input, 5);
print_r($top);

TA貢獻1836條經驗 獲得超5個贊
$topMatches = new SplMinHeap();
/* Building the list */
while($user = mysqli_fetch_assoc($users)){
.. calculate score of the $user against the inputted word ..
if($topMatches->count() === $k)
if($topMatches->top()[0] < $score) //haven't && both if's cause ->top will give error when heap empty
$topMatches->extract();
if($topMatches->count() !== $k)
$topMatches->insert([$score, $user['id']]);
}
輸出上述創建的最小堆:
檢查其是否為 0。如果是的話.下一個:$topMatchesisEmpty()count()return;
do{
list($score, $userid) = $topMatches->extract();
//echoing
}while($topMatches->valid());
- 2 回答
- 0 關注
- 135 瀏覽
添加回答
舉報