
本文介绍一种基于字母频次统计的 php 数组过滤方法,通过对比单词中各字符出现次数与给定字母池的可用次数,精准筛选出完全由且仅由该字母池(含数量约束)组成的字符串。
本文介绍一种基于字母频次统计的 php 数组过滤方法,通过对比单词中各字符出现次数与给定字母池的可用次数,精准筛选出完全由且仅由该字母池(含数量约束)组成的字符串。
在实际开发中,常需根据一组「可用字母及其最大使用次数」来验证或筛选单词(例如拼字游戏、密码生成、词库匹配等场景)。本例要求:给定字母数组 ['a','c','r','r'](即最多可用 1 个 'a'、1 个 'c'、2 个 'r'),从候选词数组中仅保留那些所有字符均来自该集合,且每个字符的出现次数不超过其在集合中的频次的单词。
核心思路是:
-
预统计字母池频次:使用
array_count_values()将['a','c','r','r']转为['a'=>1, 'c'=>1, 'r'=>2]; -
逐词校验:对每个单词,用
mb_str_split()(兼容多字节字符,如中文/emoji)拆分为字符数组,再统计其字符频次; - 严格比对:遍历单词的字符频次表,若某字符未在字母池中出现,或其需求数量超过池中可用数,则拒绝该单词。
以下是完整可运行代码:
$letters = ['a', 'c', 'r', 'r'];
$words = ['carr', 'car', 'arc', 'ra', 'c', 'abc', 'do', 'aa', 'rr'];
// 步骤1:构建字母池频次映射
$letterCounts = array_count_values($letters);
// 步骤2:过滤单词
$filtered = array_filter($words, function($word) use ($letterCounts) {
// 拆分单词为字符(支持 Unicode)
$chars = mb_str_split($word);
// 统计单词内各字符频次
$wordLetterCounts = array_count_values($chars);
// 步骤3:逐字符校验
foreach ($wordLetterCounts as $char => $requiredCount) {
// 若字符不在池中,或需求超限 → 排除
if (!isset($letterCounts[$char]) || $letterCounts[$char] < $requiredCount) {
return false;
}
}
return true;
});
// 输出结果(注意:array_filter 保留原始键名)
$filtered = array_values($filtered); // 可选:重置索引
var_dump($filtered);
// 输出:array(6) { [0]=> string(4) "carr" [1]=> string(3) "car" [2]=> string(3) "arc" [3]=> string(2) "ra" [4]=> string(1) "c" [5]=> string(2) "rr" }✅ 关键注意事项:
立即学习“PHP免费学习笔记(深入)”;
- 务必使用
mb_str_split()替代str_split(),避免 UTF-8 编码下中文、emoji 等多字节字符被错误切分; -
array_filter()默认保留原数组键名,如需连续数字索引,请调用array_values()重置; - 该逻辑区分大小写(如
'A'与'a'视为不同字符),如需忽略大小写,可在统计前统一转为小写(mb_strtolower($word)); - 时间复杂度为 O(N×M),其中 N 是单词数,M 是平均单词长度,适用于中等规模数据;超大规模场景建议预编译正则或使用 Trie 优化。
此方法逻辑清晰、扩展性强——只需调整 $letters 数组,即可快速适配不同字母资源约束场景,是 PHP 字符串精确匹配任务的稳健实践方案。



















