Lisp 将s表达式转换为Scheme中的列表

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),以便它捕获递归的基本情况。并将转换为列表时调用的列表的

如果我有一个s表达式,例如“(12(3)(4(5))67),我将如何将其转换为类似(12(3)(4)(5))67的列表?我基本上需要从s表达式中提取所有的原子。是否有一个内置的功能可以帮助我做到这一点

(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)
> 
和的可能副本