[topic] 親子のペアからツリーを構築
Posted feedbacks - Python
Pythonだとこんな感じでしょうか。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | class Node:
def __init__(self, name):
self.name = name
self.parent = None
self.children = []
def pairs_to_trees(pairs):
nodes = {}
for parent_name, child_name in pairs:
parent = nodes.setdefault(parent_name, Node(parent_name))
child = nodes.setdefault(child_name, Node(child_name))
child.parent = parent
parent.children.append(child)
return [node for node in nodes.itervalues() if node.parent is None]
def show(node, depth):
if depth == 0:
print node.name
else:
print " " * (depth - 1) + "->" + node.name
for child in node.children:
show(child, depth + 1)
def main():
pairs = [
('A', 'B'),
('B', 'C'),
('C', 'D'),
('C', 'E'),
('A', 'F'),
('D', 'X'),
('Y', 'Z'),
('Z', 'C'),
]
for tree in pairs_to_trees(pairs):
show(tree, 0)
if __name__ == '__main__':
main()
|


hu2 #6327() [ Common Lisp ] Rating0/0=0.00
親子ペア定義群からツリー構造をつくります ・親子ペア定義 ※親->子 A->B B->C C->D C->E A->F D->X Y->Z Z->C ・ツリー A ->B ->C ->D ->X ->E ->F Y ->Z ->C ->D ->X ->E; 親子ペア定義 (setf pair-lst '((a b) (b c) (c d) (c e) (a f) (d x) (y z) (z c) )) ;; 同一の親を持つペアをマージする ;; ex) ((p1 c1) (p1 c2) (p2 c3) (p2 c4)) -> ((p1 c1 c2) (p2 c3 c4)) (defun gen-fmly-lst (plst) (defun merge-lst (frst rst) (if (null rst) frst (if (eq (car frst) (caar rst)) (merge-lst (append frst (cdar rst)) (cdr rst)) (merge-lst frst (cdr rst))))) (labels ((rec (lst acc) (if (null lst) acc (if (member (caar lst) acc :key #'car) (rec (cdr lst) acc) (rec (cdr lst) (cons (merge-lst (car lst) (cdr lst)) acc)))))) (rec plst nil))) ;; fmlyのリストからツリーを生成する (defun gen-fmly-tr (fmly-lst) (labels ((rec (flst acc) (if (null flst) acc ; hook前のfmlyをhook後のfmly(n次元リスト)に置き換えて処理をする (let* ((nD-fmly (car (member (caar flst) acc :key #'car))) (othr (other nD-fmly acc))) ; fmlyをhook処理し、一箇所もhookできなかったらfmlyをそのままaccに加える (if (equal othr (hook nD-fmly othr)) (rec (cdr flst) (cons nD-fmly othr)) (rec (cdr flst) (hook nD-fmly othr))))))) (rec fmly-lst fmly-lst))) ;; リストからobjを除いたリストを取得する (defmacro other (obj lst) `(remove-if #'(lambda (x) (equal ,obj x)) ,lst)) ;; リストのcarと一致するatomをツリーの中で見つけた場合、該当atomをリストで置き換える ;; ex) (hook '(a x) '(a (b a) (c (d a)))) -> ((a x) (b (a x)) (c (d (a x)))) (defun hook (lst tree) (cond ((eq (car lst) tree) lst) ((atom tree) tree) (t (cons (hook lst (car tree)) (hook lst (cdr tree)))))) (defun main () (gen-fmly-tr (gen-fmly-lst pair-lst))) ; 実行すると、下記の構造が得られる ; ((A (B (C (D X) E)) F) (Y (Z (C (D X) E)))) ; インデントすると ;((A ; (B ; (C ; (D ; X) ; E)) ; F) ; (Y ; (Z ; (C ; (D ; X) ; E))) ; )Rating0/0=0.00-0+
[ reply ]