首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 陣列去重後取最大/最小 Top N 實作:array_unique + sort + array_slice 組合拳

     編輯:PHP 相關知識

PHP 陣列去重後取最大/最小 Top N 實作:array_unique + sort + array_slice 組合拳

從大量數值陣列中快速找出不重複的最大/最小前 N 個,是統計分析常見需求。本文展示標準庫函數組合實現,並分析時間複雜度與大數據優化方案。

標準實作 (適用 10 萬級以下)

<?php
// 1. 生成測試資料:1 萬個 1-100000 隨機數
$data = [];
for ($i = 0; $i < 10000; $i++) {
    $data[] = random_int(1, 100000);
}

// 2. 去重
$unique = array_unique($data); // O(n) 平均,保留首次出現的鍵值

// 3. 排序 (由小到大)
sort($unique); // O(k log k), k = unique count, 重設鍵值為 0..k-1

// 4. 取最小 Top 10
$minTop10 = array_slice($unique, 0, 10); // O(1) 切片

// 5. 取最大 Top 10 (需倒序或反向切片)
$maxTop10 = array_slice($unique, -10, 10); // 從尾部取 10 個
// 若需由大到小排列
$maxTop10 = array_reverse($maxTop10);

// 輸出
echo "Min Top 10:\n";
print_r($minTop10);
echo "Max Top 10:\n";
print_r($maxTop10);
?>

輸出範例

Min Top 10:
Array
(
    [0] => 16
    [1] => 19
    [2] => 22
    [3] => 31
    [4] => 40
    [5] => 49
    [6] => 71
    [7] => 74
    [8] => 80
    [9] => 92
)
Max Top 10:
Array
(
    [0] => 99997
    [1] => 99991
    [2] => 99973
    [3] => 99958
    [4] => 99955
    [5] => 99946
    [6] => 99939
    [7] => 99933
    [8] => 99927
    [9] => 99900
)

時間複雜度分析

步驟函數複雜度說明
去重array_uniqueO(n)內部用雜湊表,平均線性
排序sortO(k log k)k = 去重後數量,快速排序變體
切片array_sliceO(m)m = 取樣數 (10),極小
總計O(n + k log k)n=10000 時極快 (< 0.01s)

大數據量優化方案 (百萬級以上)

  1. 最小堆 / 最大堆 (SplMinHeap / SplMaxHeap):單次遍歷 O(n log m),m=10 固定,極度省記憶體。
    function getTopN(array $data, int $n, bool $largest = true): array {
            $heap = $largest ? new SplMinHeap() : new SplMaxHeap(); // 反向堆
            foreach ($data as $val) {
                if ($heap->count() < $n) {
                    $heap->insert($val);
                } elseif (($largest && $val > $heap->top()) || (!$largest && $val < $heap->top())) {
                    $heap->extract();
                    $heap->insert($val);
                }
            }
            $result = [];
            foreach ($heap as $v) $result[] = $v;
            return $largest ? array_reverse($result) : $result; // 排序輸出
        }
  2. 資料庫層面處理:SELECT DISTINCT val FROM table ORDER BY val DESC LIMIT 10,利用索引與查詢優化器。
  3. 計數排序 / 桶排序:若數值範圍已知且較小 (如 0-100000),O(n+k) 線性時間。

常見坑點

  • array_unique 保留首次出現的鍵值,sort() 會重設數字鍵值,關聯鍵值會丟失。
  • array_slice($arr, -10) 當陣列少於 10 個元素時,回傳整個陣列,不會報錯。
  • 浮點數去重精度問題:array_unique([0.1+0.2, 0.3]) 可能不視為相等,需先 array_map(fn($v)=>round($v,10), $arr)。

封裝為工具函數

<?php
function arrayTopN(array $data, int $n = 10, bool $unique = true, bool $largest = true): array {
    if ($unique) $data = array_unique($data);
    if ($largest) {
        rsort($data);
    } else {
        sort($data);
    }
    return array_slice($data, 0, $n);
}

// 使用
$min10 = arrayTopN($data, 10, true, false);
$max10 = arrayTopN($data, 10, true, true);
?>

標準庫組合拳簡潔高效,覆蓋 90% 場景;大數據改用堆或下推到資料庫,架構層面解決效能問題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved