我是Racket的新手,我已经阅读了很多网页信息,但是我将实现一般树作为数字列表列表时遇到了问题。 如果我从stdin接收以下预订树输入:
1 3
2 2
5 0
6 0
3 1
7 0
4 4
8 0
9 0
10 0
11 1
12 0
其中第一个数字表示节点的值,第二个值表示节点具有的子节点数。 我会尝试在将其转换为后订单之前产生我的预期结果:
'(1 (2 (5 6)) (3 ( 7)) (4 (8 9 10 11 (12))))
到目前为止,我有以下内容:
(define recurse 0)
(define (getTreeInfo)
(local ((define line (read-line)))
(if (eof-object? line)
empty
(if (= recurse 1)
(makeTree (string->number(first (string-split line))) (- (string->number(second (string-split line))) 1))
(makeTree (string->number(first (string-split line))) (string->number(second (string-split line))))))))
(define (makeTree value numChildren)
(cond
[(= numChildren 0) (begin (set! recurse 0)
(printf "Recurse: ~a\n" recurse)
(cons )]
[else (begin (set! recurse 1)
(printf "Recurse: ~a\n" recurse)
(cons value (getTreeInfo)))]))
代码不完整也不正确,但它是我思考过程的起点。 任何想法如何处理这种遍历?我觉得这里需要相互递归。
答案 0 :(得分:1)
我无法理解预期的结果。除了节点1
的子节点之外,子节点看起来主要包含在子列表中,并且由于11
是子树,我认为它应该是(11 (12))
。所以,在我看来,可能的结果可能看起来像'(1 ((2 (5 6)) (3 (7)) (4 (8 9 10 (11 (12))))))
,其中每个节点的子节点都在他们自己的列表中。
getTreeInfo
函数的一个版本可以采用另一个参数来跟踪当前节点所需的子节点数,并在每个递归步骤中递减它。我没有太多使用方案,所以我不确定这是不是惯用的,但这是一个例子。
;; IN is input stream, N is number of children remaining for current node
(define (getTreeInfo in n)
(if (zero? n) null ; no more children, return nil
(let ([line (map string->number (string-split (read-line)))])
(cond
[(zero? (cadr line)) (list (car line))] ; node has no children
[else
(let ([children '()])
(for ([_ (in-range (cadr line))])
(set! children (append children (getTreeInfo in 1))))
(cons (list (car line) children) (getTreeInfo in (sub1 n))))]))))
;; take input from stdin and start N at 1
(car (getTreeInfo (current-input-port) 1))
从命令行
$ racket reorder.rkt < tree.txt
'(1 ((2 (5 6)) (3 (7)) (4 (8 9 10 (11 (12))))))