【问题标题】:How to reverse a list - scheme如何反转列表 - 方案
【发布时间】:2020-12-09 12:45:00
【问题描述】:
(define (oddrev ls)
    (cond ((null? ls) ls)
          ((null? (cdr ls)) ls)
          (else (cons (car ls) (oddrev (cdr (cdr ls)))))))

我有一个返回奇数数组元素的方案,但我想在最后反转列表。 我该怎么做??

【问题讨论】:

    标签: list scheme racket


    【解决方案1】:

    简单的解决方案是添加一层间接:

    (define (oddrev-helper ls)
        (cond ((null? ls) ls)
              ((null? (cdr ls)) ls)
              (else (cons (car ls) (oddrev-helper (cdr (cdr ls)))))))
    
    (define (oddrev ls) (reverse (oddrev-helper ls)))
    

    这看起来很浪费,但比在末尾重复附加一个单例列表要高效得多。

    但是,如果您遇到过通过累加器和尾递归将递归过程转换为迭代的方法,您会注意到列表过程有逆向产生结果的习惯。

    如果您确实想要反向结果,您可以利用这一点。

    (define (oddrev-helper ls acc)
      (cond ((null? ls) acc)
            ((null? (cdr ls)) (cons (car ls) acc))
            (else (oddrev-helper (cdr (cdr ls)) (cons (car ls) acc)))))
    
    (define (oddrev ls) (oddrev-helper ls '()))
    

    【讨论】:

      【解决方案2】:

      通过尾递归(返回时省略通常的reverseing。

      (define (oddrev ls (acc '()))
          (cond ((or (null? ls) (null? (cdr ls))) acc)
                (else (oddrev (cdr (cdr ls)) (cons (car ls) acc)))))
      

      或者通过标准的高阶函数:

      (define (oddrev ls)
        (reverse (filter odd? ls)))
      

      试用:

      (oddrev '(1 2 3 4 5 6))
      ;; '(5 3 1)
      

      换行

      (cond ((or (null? ls) (null? (cdr ls))) acc)
      

      到:

      (cond ((or (null? ls) (null? (cdr ls))) (reverse acc))
      

      让它按输入顺序返回:'(1 3 5)

      【讨论】:

        猜你喜欢
        • 2016-11-16
        • 1970-01-01
        • 1970-01-01
        • 2019-07-19
        • 2016-01-16
        • 1970-01-01
        • 2011-04-25
        相关资源
        最近更新 更多