【发布时间】:2020-11-18 01:41:58
【问题描述】:
我想要一个函数,它接受一个字符串,由一个 python 格式的树组成,像这样
"[0, [1, 0]]"
并输出一个可用的球拍列表,像这样
'(0 (1 0))
我的第一步是将字符串转换为字符列表,用这个
(string->list treestring)
当在上面的字符串上调用时,会产生这个
'(#\[ #\0 #\, #\space #\[ #\1 #\, #\space #\0 #\] #\])
然后我打算检查我期望的各种字符并相应地解析它们,就像这样
(define (py-treestringlst-to-rkt-lst treestringlst result)
(cond
[(empty? treestringlst) result]
[(char=? (car treestringlst) #\[) (append (append result
但我在这里停了下来,因为我意识到我不知道如何在球拍中构建一个不闭合的括号。
我想更优雅的解决方案将涉及build-list;一个左括号 #\[ 将被解释为在每个后续字符上运行构建列表,直到找到一个右括号 #\]。
但也许我缺少一种更简单的方法,因为(如果还不清楚的话)我是一个新手敲诈者。
编辑:
非常感谢,ex nihilo 和 Óscar López。既然我犯了下面的暴行,我相信我可以更好地欣赏您的解决方案的优雅以及它们所表现出的精通。但是,我并没有假装自己是 Racket 的狂热学生,以至于我宁愿在续集之前阅读你的书,从而避免了自己的心痛。
; On the other hand, it works — kind of. Always gives a result two layers deep, but I could fix that.... enough... to bed with me
(define (py-treestringlst-to-rkt-lst treestringlst result)
(cond
[(empty? treestringlst) result]
[(char=? (car treestringlst) #\[) (py-treestringlst-to-rkt-lst (cdr treestringlst) (append result (build-list 1 (lambda (x) '()))))]
[(char=? (car treestringlst) #\]) (py-treestringlst-to-rkt-lst (cdr treestringlst) (append result '(bracket)))]
[(and (char=? (car treestringlst) #\0) (list? (last result))) (py-treestringlst-to-rkt-lst (cdr treestringlst) (reverse (cons (reverse (cons 0 (reverse (car (reverse result))))) (cdr (reverse result)))))]
[(and (char=? (car treestringlst) #\1) (list? (last result))) (py-treestringlst-to-rkt-lst (cdr treestringlst) (reverse (cons (reverse (cons 1 (reverse (car (reverse result))))) (cdr (reverse result)))))]
[(and (char=? (car treestringlst) #\0) (not (list? (last result)))) (py-treestringlst-to-rkt-lst (cdr treestringlst) (append result '(0)))]
[(and (char=? (car treestringlst) #\1) (not (list? (last result)))) (py-treestringlst-to-rkt-lst (cdr treestringlst) (append result '(1)))]
[else (py-treestringlst-to-rkt-lst (cdr treestringlst) result)]))
(define (cleanit lst)
(filter (lambda (x) (not (equal? x '()))) (filter (lambda (x) (not (equal? x 'bracket))) lst)))
; Example call
(cleanit (py-treestringlst-to-rkt-lst '(#\[
#\[
#\0
#\,
#\space
#\1
#\]
#\,
#\space
#\0
#\,
#\space
#\1
#\,
#\space
#\[
#\0
#\,
#\space
#\1
#\]
#\,
#\space
#\0
#\,
#\space
#\1
#\,
#\space
#\0
#\,
#\space
#\[
#\1
#\,
#\space
#\0
#\]
#\]) '()))
编辑 2(re: ex nihilo 的编辑和 tfb 的回复和评论):
确实,从无到有,我只是想出了同样的事情,使用你原来的 brackets->parenths 函数。
说我疯了,tfb,但是这个
(define (brackets->parenths s)
(read
(open-input-string
(list->string (map (lambda (x)
(case x
[(#\[) #\(]
[(#\]) #\)]
[(#\') #\"]
[else x]))
(remove* '(#\,)
(string->list s)))))))
(brackets->parenths "['get', ['me', 'for'], 'not']")
在我看来,实际上比这更干净
(require json)
(string->jsexpr (string-replace "['get', ['me', 'for'], 'not']" "\'" "\""))
也许是因为如果我的输入变得奇怪,似乎会更容易操作。
【问题讨论】:
-
Racket does not allow single quotes for string literals;单引号在 Lisps 中有不同的含义。此外,您的示例字符串缺少单引号;)我扩展了我的答案以处理您的新输入。
标签: racket