再帰を使う以外に書けない。
行っている内容はリストの要素を走査して木をつくるというもの
- 減少したらそこで打ち切り
- 要素の値が深さを決めるのではなく、現在の値との大小関係
実行結果
(list->tree '(1 1 1 1)) ; => (1 1 1 1) (list->tree '(0 1 1 2 2 1 1 2 1 0)) ; => (0 (1 1 (2 2) 1 1 (2) 1) 0) (list->tree '(0 1 2 3 4 5 1 0)) ; => (0 (1 (2 (3 (4 (5)))) 1) 0) (list->tree '(1 2 1 2)) ; => (1 (2) 1 (2)) (list->tree '(1 3 5 3)) ; => (1 (3 (5) 3)) (list->tree '(1 0)) ; => (1)
code
(use util.match :only (match)) (define (list->tree L) (define (remove-subnodes e xs) (or (member e xs) '())) (let loop ((n (car L)) (L L)) (match L [() '()] [(n* . L*) (cond ((= n n*) (cons n (loop n L*))) ((< n n*) (cons (cons n* (loop n* L*)) (loop n (remove-subnodes n L*)))) (else '()))])))
再帰を直接使う以外方法なさそう?fold系はcdrループじゃないので無理だし。unfoldは分岐のための比較を2度行わなければならないので無駄。
break,span使う意味あまりないし。