Racket博士,帮助从列表中获取元素

时间:2017-11-21 18:09:34

标签: functional-programming scheme lisp racket

我正在研究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)]
    )
  )

所以目前,如果您运行此脚本并且类型为:(转换current_state in_string delta_fn),您将获得以下输出:

> (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))是lambda函数运行以在delta_fn列表中找到匹配项后(writeln current_state)命令的结果。我想我可以直接输入(cdr(cdr current_state))来获得该输出中的第三项,但是((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 个答案:

答案 0 :(得分:1)

您正在重复使用变量current_state。不要那样做!

首先它是0,初始状态。

然后你改变它以保持一个完全不同的值,即filter操作的结果。相反,请使用一些临时变量,因此current_state尚未更改。

现在,filter会返回您询问的值((0 "a" 0)),因为delta_fn中的所有条目都保留了与您的条件相匹配的条目,列表(0 "a" 0) 。因此,筛选后的列表中包含一个匹配的条目。

要从中找到您的下一个状态,只需致电

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

其中filtered_delta_fn将是上面提到的临时变量。

然后,递归调用现在将是

(transition next_state in_string delta_fn)

您可以使用current_state代替next_state,但这只是凌乱。让所有变量有意义,使用与其含义相对应的适当值更好。否则,很容易在所有复杂的混乱中迅速迷失。

此外,set!的使用通常不受欢迎。在Scheme中,我们通常声明一个以后要使用的新变量,比如

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