scheme - 我想了解每一行代码如何删除列表中的重复项,所以这是列表 (a b a a c c) 给出的 (a b)

标签 scheme lisp

这是代码,它在 scheme lisp 上运行良好

(define (rdup ls)
  (let loop ((ls ls) (current #f))
    (cond ((null? ls)               ())
          ((null? (cdr ls))         (if (eq? (car ls) current) () ls))
          ((eq? (car ls) (cadr ls)) (loop (cdr ls) (car ls)))
          ((eq? (car ls) current)   (loop (cdr ls) current))
          (else                     (cons (car ls) (loop (cdr ls) (car ls)))) )))

这是我尝试过的

(rdup '(a b a a a c c))

得到(a b)

我想知道每一行代码是如何工作的

最佳答案

我添加了行号并修复了缩进以便于解释:

01 (define (rdup ls)
02 (let loop ((ls ls)
03 (current #f))  
04  (cond
05   ((null? ls) '())
06   ((null? (cdr ls)) 
07        (if (eq? (car ls) current) '() ls))
08   ((eq? (car ls) (cadr ls)) 
09        (loop (cdr ls) (car ls)))
10   ((eq? (car ls) current) 
11        (loop (cdr ls) current))
12   (else (cons (car ls) 
13        (loop (cdr ls) (car ls)))))))

第 02 行:您正在使用一种特殊形式的 let 语法来创建一个命名过程,然后您可以从 let 中调用该过程。您正在(令人困惑地)在循环 ls 内定义一个变量,其名称与循环外的变量完全相同,为内部变量提供外部变量的初始值。您还定义了第二个参数 current,您为 #f 提供了初始值。

第 04 行开始一个 cond

如果 ls 为 null,第 05 行(我更正了它,因此它可以通过引用空列表来工作)返回一个空列表。这将停止该过程并展开堆栈。

第 06 行检查 cdr 是否为 null,表明您正在对列表的最后一个元素进行操作。如果是,则转到第 07 行,如果 lscar 等于 current,则返回一个空列表,或者返回ls。这也会结束该过程并展开堆栈。

第 08-09 行在一行中查找重复项,如果是,则使用 cdr 作为新列表并使用 car 作为 调用循环过程当前

第 10-11 行检查 car 是否等于 current,如果是,它调用带有 cdr 的循环过程(再次迭代在列表中)和current

如果这些条件都不满足,第 12-13 行将通过 cons 创建一个新列表 - 使用 lscarlscar< 的 cdr 上调用 let 创建的 loop 过程的结果ls

如果程序按预期工作,它应该返回 '(a b c)

这是我认为您的程序旨在运行的一个:

(define rdup
  (lambda (l)
   (reverse (let loop ((lst l)
               (c '()))
      (cond
        ((null? lst) c)
        (else
         (if (member (car lst) c)
             (loop (cdr lst) c)
             (loop (cdr lst) (cons (car lst) c)))))))))

关于scheme - 我想了解每一行代码如何删除列表中的重复项,所以这是列表 (a b a a c c) 给出的 (a b),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43270332/

相关文章:

algorithm - 辛普森规则的实现(SICP 练习 1.29)

scheme - 方案中的平台(OS)检测

lisp - Lisp 中的相等和反向函数

clojure - 为什么我在下面的代码中会得到NPE?

functional-programming - 如何在PLT方案中制作模块?

Clojure 对比其他 Lisp

scheme - 类型的空列表不起作用的缺点

scheme - 打印列表的相邻副本(方案)

lisp - ltk 的问题(普通 lisp)

lisp - 通过 SICP 工作的最佳方案实现是什么?