2016-11-04 6 views
1
(define-struct school (name students)) 
;; An SchoolChart is a (make-school Str (listof SchoolChart)) 
;; names are unique 

を検索すると、これが一般的なツリーです私は学校のチャートを持つネストされたリストのスキーム/ラケット内

(define s-chart (make-school "Tom" (list 
(make-school "James" empty) 
(make-school "Claire" 
    (make-school "David" empty) 
    (make-school "Travis" empty)) 
(make-school "Timmy" empty)))) 

言うどのように私は行くのです

(define (find-name name school)) ;;produces true if found/false if not. 

私は関数を定義すると言います再帰?この特殊なケースは問題ありませんが、各子供は無限の子供を持つことができますか?ちょうどヒントが必要です

+0

あなたは他に、現在のノードがあなたの答えであるかどうかをチェック検索する場合再帰を使用している各子がノードを残しておらず、何も見つからないときにfalseを返すか、失敗を示す何かをチェックします。 PS:無限の子供の再帰のために役立つことはありませんので、それはできません。サイクルを意味するなら、訪問先のノードを知るための構造が必要です。 – Sylwester

答えて

1

子供は限られています。
金額は任意で、マシンのメモリによってのみ制限されますが、無制限にすることはできません。

(「クレア」の子がリストされないため、そして、あなたのs-chartは、病気に形成されている。)

再帰はかなりシンプルにすることができます。

(define (find-name name school) 
    (or (string=? name (school-name school)) 
     (any (lambda (s) (find-name name s)) (school-students school)))) 

(any p ls)があれば#tあると(p e)がリストlsの少なくとも一つの要素eため#t場合にのみ:ここでは
は深さ優先探索です。

今では残っているすべては、再帰的にすべての項目をチェックし、見つかった場合は、ループの外リストに名前を追加後any ...

0

を書くことです。ただし、set!を使用する必要があります。これは、デモンストレーションの目的のためにstring-prefix?の代わりstring=?を使用しています(現在の構造で複数の名前を取得する):

(define-struct school (name students)) 

(define s-chart 
    (make-school "Tom" 
       (list 
       (make-school "James" empty) 
       (make-school "Claire" (list 
             (make-school "David" empty) 
             (make-school "Travis" empty))) 
       (make-school "Timmy" empty)))) 


(define (find-name name school) 
    (define ol '()) 
    (let loop ((s school)) 
    (cond 
     [(list? s) 
     (when (not(empty? s)) 
      (begin (loop (first s)) 
        (loop (rest s))))] 
     [else 
     (when (string-prefix? (school-name s) name) 
     (set! ol (cons (school-name s) ol))) 
     (loop (school-students s)) 
     ])) 
    ol 
) 

(find-name "T" s-chart) 

出力:

'("Timmy" "Travis" "Tom") 
関連する問題