PHP-从输入创建树

时间:2018-08-18 14:43:44

标签: php data-structures tree

我正在学习并且坚持解决这个问题:

我想创建一棵树,它有一个具有以下模式的字符串:

1[2[3,5],4[7[6,9,11],8]]

其中2和4是1的子代; 3和5是2的孩子; 7和8是4岁的孩子; 6、9和11是7岁的孩子;等等。

并打印出一个简单的树形结构图,如下所示:

            1
         /    \
        2      4
       / \    /  \
      3   5  7   8
           / | \
          6  9  11

任何帮助都会很棒。

1 个答案:

答案 0 :(得分:0)

很好的锻炼。我提出的答案不是最好的方法,而是可以改进的初始方法。

首先,需要将字符串解析为树结构。递归是一个显而易见的选择。前面有许多清理和错误处理的机会,包括使用堆栈来跟踪括号对索引。

第二,我相信在给定的已解析树结构的情况下,您要查找的输出是一个很高的顺序。如果一个节点有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 

这是一个repl,很容易搞混。