很好的练习。我提出这个答案不是最好的方法,而是一种可以改进的幼稚方法。
首先,需要将字符串解析成树形结构。递归是一个显而易见的选择。前面有许多清理和错误处理机会,包括使用堆栈来跟踪括号对索引。
其次,我相信给定已解析的树结构,您正在寻找的输出是一项艰巨的任务。如果一个节点有 60 个子节点会发生什么?考虑确定所有内容的间距并进行高度/宽度计算使我保持简单并尝试类似于tree 的方法,它可以在几行内完成并自动处理许多边缘情况。即使在这里,为长根节点添加填充也可能是一个改进点。
function parse($data) {
$result = [];
$d = "";
for ($i = 0; $i < count($data); $i++) {
if (preg_match("/^[^\[\]\,]$/", $data[$i])) {
$d = "";
while ($i < count($data) &&
preg_match("/^[^\[\]\,]$/", $data[$i])) {
$d .= $data[$i++];
}
$i--;
$result[$d] = null;
}
else if (preg_match("/^[\[\]]$/", $data[$i])) {
$closing_idx = -1;
$level = 1;
$j = $i + 1;
for (; $j < count($data); $j++) {
if ($data[$j] === "[") {
$level++;
}
else if ($data[$j] === "]") {
if (--$level === 0) {
$closing_idx = $j;
break;
}
}
}
$cpy = [];
for ($k = $i + 1; $k < $closing_idx; $k++) {
$cpy[] = $data[$k];
}
$result[$d] = parse($cpy);
$i = $closing_idx;
}
}
return $result;
}
function print_tree($tree, $depth=0) {
if ($tree) {
foreach ($tree as $root => $child) {
echo str_repeat(" ", $depth * 6);
echo "$root " . ($child ? "────┐" : "") . "\n";
print_tree($child, $depth + 1);
}
}
}
$data = "1[2[3,5],4[7[6,9,11],8]]";
print_tree(parse(str_split($data)));
输出:
1 ────┐
2 ────┐
3
5
4 ────┐
7 ────┐
6
9
11
8