如何使用PHP将扁平编号列表转换为层级化列表?
问题:将扁平数组转换为层级化结构(罗马数字层级处理)
需求说明
需要把一组扁平的数组元素,按照层级规则转换为嵌套形式:
原始扁平形式
(a) (b) (1) (2) (i) (ii) (3) (4) (c) (d) (1)
目标层级形式
(a) (b) (b)(1) (b)(2) (b)(2)(i) (b)(2)(ii) (b)(3) (b)(4) (c) (d) (d)(1)
尝试的代码
用户尝试了以下PHP代码,但罗马数字部分处理错误:
$elements = ['a', 'b', '1', '2', 'i', 'ii', '3', '4', 'c', 'd', '1']; $newElements = []; $currentMain = ''; foreach ($elements as $element) { if (ctype_alpha($element)) { $currentMain = $element; $newElements[] = $element; } elseif (is_numeric($element)) { $newElements[] = $currentMain . '(' . $element . ')'; } else { $newElements[] = $currentMain . '(' . end($newElements) . ')' . '(' . $element . ')'; } } print_r($newElements);
问题根源
原代码仅维护了一级主元素(currentMain),没有跟踪完整的层级链。遇到罗马数字时,错误地将最后一个已生成的完整项再次嵌套,导致格式混乱。正确逻辑应该是根据元素类型维护层级栈,不同类型元素对应不同层级深度。
可行解决方案
通过维护一个层级栈,根据元素类型(字母、阿拉伯数字、罗马数字)动态调整栈内容,再拼接生成层级化项:
$elements = ['a', 'b', '1', '2', 'i', 'ii', '3', '4', 'c', 'd', '1']; $newElements = []; $levelStack = []; // 判断是否为罗马数字的辅助函数 function isRomanNumeral($str) { return preg_match('/^[ivxlcdm]+$/i', $str); } foreach ($elements as $element) { if (ctype_alpha($element) && strlen($element) == 1) { // 字母是顶级层级,清空栈并压入当前元素 $levelStack = [$element]; $newElements[] = "($element)"; } elseif (is_numeric($element)) { // 数字是二级层级,保留顶级字母,压入当前数字 $levelStack = [$levelStack[0], $element]; $newElements[] = "({$levelStack[0]})($element)"; } elseif (isRomanNumeral($element)) { // 罗马数字是三级层级,保留前两级,压入当前罗马数字 $levelStack = array_slice($levelStack, 0, 2); $levelStack[] = $element; $newElements[] = "({$levelStack[0]})({$levelStack[1]})($element)"; } } print_r($newElements);
代码说明
- 层级栈
$levelStack:跟踪当前层级链,不同类型元素对应不同栈长度:- 字母:栈长度为1(仅顶级元素)
- 阿拉伯数字:栈长度为2(顶级字母+二级数字)
- 罗马数字:栈长度为3(顶级字母+二级数字+三级罗马数字)
- 辅助函数
isRomanNumeral:通过正则判断元素是否为罗马数字(支持大小写) - 拼接规则:直接从栈中取出对应层级元素,按照
(层级1)(层级2)(层级3)格式拼接
输出结果
执行后将得到完全符合目标形式的数组:
Array ( [0] => (a) [1] => (b) [2] => (b)(1) [3] => (b)(2) [4] => (b)(2)(i) [5] => (b)(2)(ii) [6] => (b)(3) [7] => (b)(4) [8] => (c) [9] => (d) [10] => (d)(1) )
内容的提问来源于stack exchange,提问作者Dan Glauber
相关产品推荐
相关产品推荐

