Lisp 将s表达式转换为Scheme中的列表
如果我有一个s表达式,例如“(12(3)(4(5))67),我将如何将其转换为类似(12(3)(4)(5))67的列表?我基本上需要从s表达式中提取所有的原子。是否有一个内置的功能可以帮助我做到这一点Lisp 将s表达式转换为Scheme中的列表,lisp,scheme,racket,Lisp,Scheme,Racket,如果我有一个s表达式,例如“(12(3)(4(5))67),我将如何将其转换为类似(12(3)(4)(5))67的列表?我基本上需要从s表达式中提取所有的原子。是否有一个内置的功能可以帮助我做到这一点 (define (convert-to-list s) ... ) 到目前为止,我的算法是,如果第一个元素是原子,则将其附加到列表中。如果第一个元素是一个列表,那么获取该元素的car,然后使用该函数调用函数(convert to list),以便它捕获递归的基本情况。并将转换为列表时调用的列表的
(define (convert-to-list s) ... )
到目前为止,我的算法是,如果第一个元素是原子,则将其附加到列表中。如果第一个元素是一个列表,那么获取该元素的car,然后使用该函数调用函数(convert to list),以便它捕获递归的基本情况。并将转换为列表时调用的列表的cdr附加到该列表的car。我试着从计算机程序的结构和解释来教我自己,我只是在尝试随机的东西。事实证明,递归地这样做比我预期的要困难得多 你的算法看起来不错,只是少了一两步
(定义(展平lst);“展平”是此函数的更好名称
(续)
((空lst)无)
不要担心我在没有任何检查的情况下打电话(flatte(cdrlst));
上面的箱子处理它
(原子弹(汽车lst));汽车没问题
(cons(车辆lst)(展平(cdr lst)))
((cons?(car lst));汽车仍然需要整平;注意使用
在此处添加(汽车列表可以有任意数量的元素)
(附加(展平(汽车起落架))(展平(cdr起落架()())))
在处理第一个元素的(flatte(car lst))
调用和递归处理列表其余部分的(flatte(cdr lst))
调用之间,输入列表以一个平面列表结束(即,不使用任何元素)
(警告:我不是方案专家;上面的代码可能包含错误。)您的算法看起来不错,只是缺少一两步
(定义(展平lst);“展平”是此函数的更好名称
(续)
((空lst)无)
不要担心我在没有任何检查的情况下打电话(flatte(cdrlst));
上面的箱子处理它
(原子弹(汽车lst));汽车没问题
(cons(车辆lst)(展平(cdr lst)))
((cons?(car lst));汽车仍然需要整平;注意使用
在此处添加(汽车列表可以有任意数量的元素)
(附加(展平(汽车起落架))(展平(cdr起落架()())))
在处理第一个元素的(flatte(car lst))
调用和递归处理列表其余部分的(flatte(cdr lst))
调用之间,输入列表以一个平面列表结束(即,不使用任何元素)
(警告:我不是方案专家;上面的代码可能包含错误。)您的案例应该包括空列表、一个原子、(汽车)是原子,(汽车)是列表 这是可行的,尽管我因为不记得内置的函数是什么而痛斥了一个list append函数。在高级学生学校工作
(define (list-glue left-list right-list)
(cond
((null? left-list) right-list)
(else (cons (car left-list) (list-glue (cdr left-list) (right-list))))))
(define (convert-to-list s)
(cond
((null? s) '())
((not (list? s)) (cons s (quote ())))
((not (list? (car s))) (cons (car s) (convert-to-list (cdr s))))
(else
(list-glue
(convert-to-list (car s))
(convert-to-list (cdr s))))))
你的案例应该包括空列表,一个原子,(cars)是一个原子,(cars)是一个列表 这是可行的,尽管我因为不记得内置的函数是什么而痛斥了一个list append函数。在高级学生学校工作
(define (list-glue left-list right-list)
(cond
((null? left-list) right-list)
(else (cons (car left-list) (list-glue (cdr left-list) (right-list))))))
(define (convert-to-list s)
(cond
((null? s) '())
((not (list? s)) (cons s (quote ())))
((not (list? (car s))) (cons (car s) (convert-to-list (cdr s))))
(else
(list-glue
(convert-to-list (car s))
(convert-to-list (cdr s))))))
从字面上回答你的问题,“有没有一个内置的功能来帮助我做到这一点?”,在球拍是有。正是这样:“将任意的S表达式结构的对展平为一个列表。”
然而,思考如何编写flant
是一个很好的练习
克里斯·杰斯特·杨的评论与优雅的方式有关。如果她将此作为答案而不是评论发布,我建议将她的答案标记为已接受,而不是我的答案。:) 直截了当地回答您的问题,“有没有内置的函数来帮助我完成这项工作?”,在Racket中有。正是这样:“将任意的S表达式结构的对展平为一个列表。”
然而,思考如何编写flant
是一个很好的练习
克里斯·杰斯特·杨的评论与优雅的方式有关。如果她将此作为答案而不是评论发布,我建议将她的答案标记为已接受,而不是我的答案。:) 现在,如果您想要更快的实现,您根本不需要
append
其思想是将附加到的内容作为参数传递。我称之为尾巴。
如果您有一个空的s-exp,您只需返回尾部,因为它没有任何可添加的内容
我得到了代码,flat
和flat2
,其中flat
使用了match
语句,而flat2
只使用了cond
,我觉得读起来有点难,但我会提供给你,以防你还没有看到match
#lang racket
(define (flat s-exp tail)
(match s-exp
['() tail]
[(cons fst rst)
(let ([new-tail (flat rst tail)])
(flat fst new-tail))]
[atom
(cons atom tail)]))
(define (flat
(cond
[(empty? s-exp) tail]
[(list? s-exp)
(let* ([fst (first s-exp)]
[rst (rest s-exp)]
[new-tail (flat])
(flat fst new-tail))]
[#t
(cons s-exp tail)]))
要使用它们,请像这样称呼它们(flat'(1()(2(3))4())
==>”(1234)
。
您需要为它们提供一个空列表,以便开始使用。现在,如果您想要更快的实现,您根本不需要
追加
其思想是将附加到的内容作为参数传递。我称之为尾巴。
如果您有一个空的s-exp,您只需返回尾部,因为它没有任何可添加的内容
我得到了代码,flat
和flat2
,其中flat
使用了match
语句,而flat2
只使用了cond
,我觉得读起来有点难,但我会提供给你,以防你还没有看到match
#lang racket
(define (flat s-exp tail)
(match s-exp
['() tail]
[(cons fst rst)
(let ([new-tail (flat rst tail)])
(flat fst new-tail))]
[atom
(cons atom tail)]))
(define (flat
(cond
[(empty? s-exp) tail]
[(list? s-exp)
(let* ([fst (first s-exp)]
[rst (rest s-exp)]
[new-tail (flat])
(flat fst new-tail))]
[#t
(cons s-exp tail)]))
要使用它们,请像这样称呼它们(flat'(1()(2(3))4())
==>”(1234)
。
您需要提供空列表,以便它们开始使用。只需在子列表和rest列表上递归即可。您可以看到这段代码读起来有多容易。例如:
(define (convert-to-list list)
(if (null? list)
'()
(let ((next (car list))
(rest (cdr list)))
(if (list? next)
(append (convert-to-list next) (convert-to-list rest))
(cons next (convert-to-list rest))))))
> (convert-to-list '(a b c))
(a b c)
> (convert-to-list '((a b) (((c d) e f) g h) i j))
(a b c d e f g h i j)
>
这可以通过在子列表和rest列表上递归来实现。您可以看到这段代码读起来有多容易。例如:
(define (convert-to-list list)
(if (null? list)
'()
(let ((next (car list))
(rest (cdr list)))
(if (list? next)
(append (convert-to-list next) (convert-to-list rest))
(cons next (convert-to-list rest))))))
> (convert-to-list '(a b c))
(a b c)
> (convert-to-list '((a b) (((c d) e f) g h) i j))
(a b c d e f g h i j)
>
和的可能副本