給定任意長度字符串,統計每個字符出現的次數,並按次數降序排列。本文對比三種實現思路,分析優劣。
<?php
function countStr($str) {
$arr = str_split($str); // 字符串轉數組
$arr = array_count_values($arr); // 統計值出現次數
arsort($arr); // 降序排序保持鍵值關聯
return $arr;
}
$str = "asdfgfdas323344##\$\$fdsdfg*\$\*\$\*\$\*\$\$\$\$443563536254fas";
print_r(countStr($str));
?>
核心函數:str_split、array_count_values、arsort。
優點:代碼極少,可讀性高,執行效率高(C 底層實現)。
缺點:對多字節字符(中文)支持需用 mb_str_split (PHP 7.4+) 或 preg_split('//u')。
<?php
function countStr2($str) {
$arr = str_split($str);
$result = [];
foreach ($arr as $char) {
if (!isset($result[$char])) {
$result[$char] = 1;
} else {
$result[$char]++;
}
}
arsort($result);
return $result;
}
$str = "asdfgfdas323344##\$\$fdsdfg*\$\*\$\*\$\*\$\$\$\$443563536254fas";
var_dump(countStr2($str));
?>
優點:邏輯清晰,易於擴展(如同時統計大小寫不敏感)、移植到其他語言。
缺點:PHP 循環比內置函數慢。
<?php
function countStr3($str) {
$arr = str_split($str);
$unique = array_unique($arr); // 獲取不重複字符
$result = [];
foreach ($unique as $char) {
$result[$char] = substr_count($str, $char); // 遍歷字符串計數
}
arsort($result);
return $result;
}
$str = "asdfgfdas323344##\$\$fdsdfg*\$\*\$\*\$\*\$\$\$\$443563536254fas";
var_dump(countStr3($str));
?>
缺點:array_unique + substr_count 導致多次遍歷字符串,時間複雜度 O(n²),大字符串極慢,不推薦生產使用。
| 方法 | 執行時間(相對) | 內存峰值 | 推薦指數 |
|---|---|---|---|
| 方法一 (內置函數) | 1x (基準) | 低 | ⭐⭐⭐⭐⭐ |
| 方法二 (手動遍歷) | ~3-5x | 中 | ⭐⭐⭐ |
| 方法三 (去重計數) | ~50x+ | 高 | ⭐ |
<?php
// PHP 7.4+ 使用 mb_str_split
$arr = mb_str_split($str, 1, 'UTF-8');
// 兼容舊版本
$arr = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY);
// 後續邏輯相同
?>
首選方法一,利用 PHP 豐富的數組函數實現最優性能與可讀性。方法二適合教學或需自定義邏輯場景。方法三僅作為反面教材理解算法複雜度差異。