2017-11-21 6 views
1

私はDr. Racketの有限状態機械に取り組んでおり、移行関数の次の状態を抽出する助けが必要です。Dr. Racket、リストから要素を取得するのを手助けしてください

現在、文字列内の文字がアルファベットと一致するかどうか、または最後の状態が最終状態のリストにあるかどうか、あるいは状態から状態への遷移が得られるまで再帰的に。私は今で午前のはここ

は次のとおりです。

#lang racket 
(require math/array) 

(define in_string (list "a" "b" "b" "b")) 
(define alphabet (list "a" "b")) 
(define initial_state 0) 
(define final_states (list 2)) 
(define delta_fn (list 
         (list 0 "a" 0) 
         (list 0 "b" 1) 
         (list 1 "a" 0) 
         (list 1 "b" 1))) 

(define current_state initial_state) 

(define (transition current_state in_string delta_fn) 
    (writeln current_state) 
    (writeln in_string) 
    (writeln delta_fn) 
    (cond 
    [(empty? in_string) (writeln current_state)] 
    [else 
    (let ([input (car in_string)]) 
     (set! current_state (filter (lambda (v) 
            (match v 
             [(list (== current_state) (== input) _) #t] 
             [_ #f])) 
            delta_fn))) 
    (writeln current_state)] 
    ;(transition current_state in_string delta_fn)] 
    ) 
) 

このスクリプトと種類実行のであれば、現時点では、:(delta_fnをin_string遷移current_state)を、あなたは次のような出力が得られます。

> (transition current_state in_string delta_fn) 
0 
("a" "b" "b" "b") 
((0 "a" 0) (0 "b" 1) (1 "a" 0) (1 "b" 1)) 
((0 "a" 0)) 

最後の行:((0 "a" 0))は、delta_fnリストで一致を見つけるためにラムダ関数が実行された後の(writeln current_state)コマンドの結果です。私はちょうど(cdr(cdr current_state))その出力に3番目の項目を取得することができますが、((0 "a" 0))リストではないと私はリストのようにそれを操作することはできませんと思った。

私の質問は次のとおりです。((0 "a" 0))は何ですか? current_stateがなぜ '(0 "a" 0 ")の代わりに設定されるのですか?

すべてのヘルプは、私は、一般的に、関数型プログラミングに非常に新しいだということを知っているので、小さな言葉=


P

ソリューションを使用してください、大幅にいただければ幸いです!

(define (transition current_state in_string delta_fn) 
    (cond 
    [(empty? in_string) (writeln current_state)] 
    [else 
    (let ([input (car in_string)]) 
     (set! filtered_delta_fn (filter (lambda (v) 
            (match v 
             [(list (== current_state) (== input) _) #t] 
             [_ #f])) 
            delta_fn))) 
    (set! next_state (car (cdr (cdr (car filtered_delta_fn))))) 
    (transition next_state (cdr in_string) delta_fn)] 
    ) 
) 

答えて

1

変数current_stateを再利用しています。それをしないでください!

最初は0で、初期状態でした。

次に、filterの操作の結果、まったく異なる値を保持するように変更します。その代わりに、一時変数を使用してください。したがって、current_stateはまだ変更されていません。

は今、なぜならdelta_fn内のすべてのエントリのあなたは尋ねる価値filter戻り、((0 "a" 0))は、それはあなたの基準、リスト(0 "a" 0)に一致するものを保持しました。フィルタリングされたリストには、一致するエントリが1つ保持されます。

単にfiltered_delta_fnは、上記の一時的な変数になります

(set! next_state (car (cdr (cdr (car filtered_delta_fn))))) 
;        (0 "a" 0) 
;       ("a" 0) 
;      (0) 
;     0 

を呼び出し、それから、あなたの次の状態を検索します。

その後、再帰呼び出しは、今あなたはnext_stateの代わりにcurrent_stateを使用することができますが、それはただ厄介だ

(transition next_state in_string delta_fn) 

になります。あなたの変数をすべて意味のあるものにし、その意味に対応する適切な値を持つ方がずっと良いです。それ以外の場合は、複雑な混乱の中ですばやく失われることは容易です。

また、set!の使用は、通常、面倒です。Schemeでは、通常、新しい変数を次のように宣言します。

(let ((next_state (car (cdr .....)))) 
     ; recursive call ..... 
+0

ありがとうございました!これは私のためにはうまくいきました。私はfsmが入る最終状態を得るために関数 "transition"を使うことができます。そして今はそれが受け入れ可能な状態であるかどうかを調べることができます。あなたの指針を反映するようにコードを更新しました。私はセットを変更します!次の練習にしましょう! –

関連する問題