【问题标题】:Dr. Racket, help getting element from a listRacket 博士,帮助从列表中获取元素
【发布时间】:2018-05-05 07:36:00
【问题描述】:

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

所以此刻,如果你运行这个脚本和类型:(transition 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)]
    )
  )

【问题讨论】:

    标签: functional-programming scheme lisp racket


    【解决方案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 .....
    

    【讨论】:

    • 非常感谢!这对我来说效果很好,现在我可以使用函数“transition”来获得我的 fsm 将处于的最终状态,现在我可以检查这是否是可接受的状态。我更新了我的代码以反映您的指导。我要换套!让作为我的下一个练习!
    猜你喜欢
    • 2018-11-07
    • 1970-01-01
    • 2023-03-26
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-24
    • 1970-01-01
    相关资源
    最近更新 更多