Recursion 我怎样才能撤销列表?

Recursion 我怎样才能撤销列表?,recursion,scheme,reverse,Recursion,Scheme,Reverse,在Scheme中反转列表的功能是什么 它需要能够处理嵌套列表。因此,如果您执行类似于(reverse'(a(bcd)e))的操作,您将获得(e(bcd)a)作为输出 我应该如何处理这个问题?我不是在寻找答案,而是在寻找能帮助我学习的东西。使用: (define (reverse1 l) (if (null? l) nil (append (reverse1 (cdr l)) (list (car l))) ) ) 说明: 规则: 如果列表为空,则反向列表也为空 否则

在Scheme中反转列表的功能是什么

它需要能够处理嵌套列表。因此,如果您执行类似于
(reverse'(a(bcd)e))
的操作,您将获得
(e(bcd)a)
作为输出

我应该如何处理这个问题?我不是在寻找答案,而是在寻找能帮助我学习的东西。

使用:

(define (reverse1 l)
  (if (null? l)
     nil
     (append (reverse1 (cdr l)) (list (car l)))
  )
)
说明:

规则:

  • 如果列表为空,则反向列表也为空
  • 否则,在列表的尾部后面添加列表的第一个元素
  • 请按以下方式查看此代码:

    reverse1
    是函数名,l是参数。如果列表为空,则反之亦然。 否则,使用列表尾部的(cdr l)调用
    reverse1
    函数,并将其附加到作为列表制作的第一个列表(car l)中

    在您的示例(伪代码)中:

    它使用一个累加器变量来反转列表,从传入列表中取出第一个元素,并将其视为累加器的前面。它隐藏了累加器获取函数,只公开获取列表的函数,因此调用方不必传入空列表。这就是为什么我有我的反向2

    (my-reverse-2 '(a (b c d) e) '()); will call
    (my-reverse-2 '((b c d) e)  '(a)); which will call
    (my-reverse-2 '(e)  '((b c d) a)); which will call
    (my-reverse-2 '() '(e (b c d) a)); which will return
    '(e (b c d) a)
    
    因为
    my-reverse-2
    中的最后一个函数调用是对
    my-reverse-2
    的调用,并且返回值是直接传递的(第一个调用的返回值是第二个调用的返回值,依此类推)
    my-reverse-2
    是尾部优化的,这意味着它不会耗尽堆栈空间。所以,只要你愿意,就可以用列表来称呼它

    如果要将其应用于嵌套列表,请使用以下内容:

    (define (deep-reverse ls)
      (define (deep-reverse-2 ls acc)
        (if (null? ls)
            acc
            (if (list? (car ls))
                (deep-reverse-2 (cdr ls) (cons (deep-reverse (car ls)) acc))
                (deep-reverse-2 (cdr ls) (cons (car ls) acc)))))
      (deep-reverse-2 ls '()))
    
    在将元素添加到列表之前,检查元素是否是列表,如果是,则首先将其反转。 由于它调用自身来反转内部列表,因此它可以处理任意嵌套

    (深倒(a(b c d)e))
    ->
    ”(e(d c b)a)
    ,尽管存在嵌套列表,但其字母顺序与字母顺序相反。 其评价如下:

    (deep-reverse-2 '(a (b c d) e) '()); Which calls
    (deep-reverse-2 '((b c d) e)  '(a))
    (deep-reverse-2 '(e) (cons (deep-reverse-2 '(b c d) '()) '(a)))
    (deep-reverse-2 '(e) (cons (deep-reverse-2 '(c d)  '(b)) '(a)))
    (deep-reverse-2 '(e) (cons (deep-reverse-2 '(d)  '(c b)) '(a)))
    (deep-reverse-2 '(e) (cons '(d c b) '(a)))
    (deep-reverse-2 '(e)  '((d c b) a))
    (deep-reverse-2 '() '(e (d c b) a))
    '(e (d c b) a)
    

    这是创建应用于嵌套列表的反向函数的一种方法:

    (define (reverse-deep l)
      (map (lambda (x) (if (list? x) (reverse-deep x) x)) (reverse l)))
    
    伪代码解释:
    开始时,请像平时一样反转列表
    然后对于反向列表中的每个元素:
    -如果元素本身是列表:递归地应用该过程
    -否则:不要触摸元素

    我使用的代码类似于:

    我是从记忆中复制出来的。可能有一些错误。如果是这样的话,我会更正代码。但是所使用的技术类似于小模式中给出的嵌套列表的命令:)。我在Racket登记了


    (deep rev list'((12)(3)((45)))返回(((54))(3)(21))

    您可以使用foldr简单地反转列表中的元素:

    (foldr (lambda (a r) (append r (list a))) empty lst)
    

    这是一个反向函数,我比Scheme更喜欢它

    它仅使用匹配模式匹配功能

    (define/match (rev l)
        [('()) '()]
        [((list a ... b)) (cons b (rev a))])
    
    > (rev '(a (b c d) e))
    '(e (b c d) a)
    
    我的解决方案:

    (define (rvrs ls)
      (if (null? ls)
        empty
        (append (rvrs (cdr ls)) (cons (car ls) empty))))
    

    请注意,这个答案是用Common Lisp编写的,它使用
    nil
    而不是
    '()
    @erjiang,这不是真的-虽然Common Lisp使用
    nil
    而Scheme不使用,但这个答案顶部定义的函数实际上是Scheme,而不是Common Lisp。你需要做一些类似于
    (define nil'())
    的事情才能让它工作。这对我来说非常好,只需要一个小的编辑(返回项而不是nil):(define(rev items)(if(null?items)items(append)(rev(cdr items))(list(car items)))我在Petite Chez()中运行它还有一个内置的(反向)过程返回相同的结果。为了避免nil/empty列表问题,因为您已经知道l是空的from(null?l),所以这种情况下可以只返回l。不管具体是什么,这都会起作用?检查。更好的答案:(define(rev1 lst)(foldl cons’()lst))这使用O(n^2)时间和O(n^2)空间。因此,列表越长,你越不可能在耐心耗尽或记忆力耗尽之前得到答案。什么是“小阴谋家”和“DrRacket”?分别是一本书和一个在线工具?应该有一个解释。例如,这个想法是什么?它与以前的答案有什么不同?
    (foldr (lambda (a r) (append r (list a))) empty lst)
    
    (define/match (rev l)
        [('()) '()]
        [((list a ... b)) (cons b (rev a))])
    
    > (rev '(a (b c d) e))
    '(e (b c d) a)
    
    (define (rvrs ls)
      (if (null? ls)
        empty
        (append (rvrs (cdr ls)) (cons (car ls) empty))))