PHP如何压缩字符数组 将连续a-z/A-Z/0-9转为区间短数组
实现方案
先明确合并规则:
- 仅合并三类ASCII字符的连续序列:大写字母
A-Z、小写字母a-z、数字0-9,三类字符之间即使ASCII值相邻(比如Z和a)也不跨类合并 - 非字母数字的特殊符号无论是否ASCII相邻,都单独保留
- 以下实现完全匹配示例的输出顺序,即保留原数组的字符排列顺序,仅合并位置相邻、且满足同类型、ASCII值连续递增的字符
完整代码
/** * 获取字符类型:1=大写字母 2=小写字母 3=数字 0=特殊符号 */ function getCharType(string $char): int { $ascii = ord($char); if ($ascii >= ord('A') && $ascii <= ord('Z')) { return 1; } if ($ascii >= ord('a') && $ascii <= ord('z')) { return 2; } if ($ascii >= ord('0') && $ascii <= ord('9')) { return 3; } return 0; } /** * 合并相邻连续字符为区间格式 */ function compressCharSeq(array $charArr): array { $length = count($charArr); if ($length === 0) { return []; } $result = []; $segmentStart = $charArr[0]; $segmentEnd = $charArr[0]; for ($i = 1; $i < $length; $i++) { $current = $charArr[$i]; // 同类型且ASCII值连续递增,属于当前段 if (getCharType($current) === getCharType($segmentEnd) && ord($current) - ord($segmentEnd) === 1) { $segmentEnd = $current; continue; } // 不满足连续条件,保存当前段,开启新段 $result[] = $segmentStart === $segmentEnd ? $segmentStart : "{$segmentStart}-{$segmentEnd}"; $segmentStart = $current; $segmentEnd = $current; } // 保存最后一个段 $result[] = $segmentStart === $segmentEnd ? $segmentStart : "{$segmentStart}-{$segmentEnd}"; return $result; } // 测试示例 $input = array('A','B','C','F','a','b','c','d','e','f','h','i','j','k','l','o','q','!','?','0','1','2','3','4','9'); $output = compressCharSeq($input); // 输出结果为 array('A-C','F','a-f','h-l','o','q','!','?','0-4','9'),和预期完全一致
扩展说明
如果输入数组的字符是乱序排列的,不需要保留原顺序,只需要输出所有连续字符区间,可以在compressCharSeq函数开头加一行排序逻辑,输出结果将按ASCII升序排列:
function compressCharSeq(array $charArr): array { sort($charArr); // 新增:按ASCII升序重排数组 $length = count($charArr); // 后续逻辑和上述代码一致 }
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

