【问题标题】:Scheme streams and circular lists方案流和循环列表
【发布时间】:2013-02-04 00:22:36
【问题描述】:

在 Scheme/Lisp 中,我正在尝试创建一个将列表转换为循环列表的函数。因此,我认为我需要构造一个无限流,其中列表的尾部指向列表的头部。

到目前为止,这是我的代码:

(define (rotate-list l1 l1copy)
  (if (null? (force (cdr l1)))
      (cons (car l1) (delay l1copy)))
      (cons (car l1) (delay (rotate-list (force (cdr l1)) l1copy))))

非常感谢所有帮助。

【问题讨论】:

    标签: list functional-programming lisp scheme circular-list


    【解决方案1】:

    不,您不需要流来制作循环列表。

    创建循环列表有两种方法,标准 Scheme 方法和 Racket 方法(因为 Racket 的 conses 是不可变的)。我将查看使用SRFI 1circular-list 函数的示例。这是参考实现:

    (define (circular-list val1 . vals)
      (let ((ans (cons val1 vals)))
        (set-cdr! (last-pair ans) ans)
        ans))
    

    这样做是在给定值列表中找到最后一对,然后set-cdr!s 将其返回到该列表的开头。很简单,对吧?

    在 Racket 中,conses 是不可变的,因此 set-cdr! 不存在。因此,Racket 是这样做的:

    (define (circular-list val1 . vals)
      (let ([ph (make-placeholder #f)])
        (placeholder-set! ph
          (cons val1 (let loop ([vals vals])
                       (if (null? vals)
                         ph
                         (cons (car vals) (loop (cdr vals)))))))
        (make-reader-graph ph)))
    

    这使用 Racket 的 make-reader-graph 函数来处理循环。非常漂亮。 :-)

    【讨论】:

    • 你能举一个在 Racket 中创建文字循环列表的例子吗? documentation 提到了类似 #0=(1 . #0#) 的内容,但 REPL 不接受此表达式。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-28
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 2021-11-29
    • 2012-08-05
    • 2011-10-14
    相关资源
    最近更新 更多