【发布时间】:2016-04-22 23:13:25
【问题描述】:
我正在尝试编写一个程序来检查列表列表是否具有特定属性(对问题不重要)。在此过程中,我发现有必要生成单个给定列表的“非对角对”列表,因此我编写了一个宏,它接受一个列表并定义对列表(笛卡尔积的列表版本集)以及我称之为该列表的“对角线”('(x x) 形式的对)。我为此编写的代码如下:
;;;These first two definitions are 'extended' car and cdr
;;;I only did this because the (prod a b) code below threw errors otherwise
(define (xcar a) (cond ((null? a) '()) ((car a))))
(define (xcdr a) (cond ((null? a) '()) ((cdr a))))
;;;This defines a pre-product, i.e. all pairs with the first element of the first list
(define (pre-prod a b)
(cond ((or (null? a) (null? b)) '())
((append (list (list (xcar a) (xcar b))) (pre-prod a (xcdr b))))))
;;;This defines the full product of the list
(define (prod a b)
(cond ((null? a) '())
((append (pre-prod a b) (prod (xcdr a) b)))))
;;;This defines the diagonal of the list
(define (diagonal a)
(cond ((null? a) '())
((append
(list (list (car a) (car a)))
(diagonal (cdr a))))))
太好了,所有代码似乎都按我想要的那样工作。接下来我需要获取 set-minus 的列表版本。我在an answer here 中找到了以下代码来执行此操作:
;;;Returns #t if x is an element of lst and #f otherwise
(define (element? x lst)
(cond ((null? lst) #f)
((eq? x (car lst)) #t)
(#t (element? x (cdr lst)))))
;;;Takes list a and removes all elements of list b from it
(define (list-minus a b)
(cond ((null? a) '())
((element? (car a) b)
(list-minus (cdr a) b))
(#t (cons (car a) (list-minus (cdr a) b)))))
很酷,这似乎可以很好地完成它需要做的事情。现在我要做的就是让 DrRacket 返回正确对的列表(删除对角线)。我认为以下代码应该这样做:
(define (proper-pairs a) (list-minus (prod a a) (diagonal a)))
现在我用一些简单的方法测试这个新函数,它应该返回'():
> (proper-pairs '(1))
=> '((1 1))
什么?我尝试了很多示例,多次修改代码,在各种列表中尝试过。我总是想出以下问题:list-minus will not remove a list from a list of lists.
问题 1:为什么list-minus 在列表列表中表现出这种异常行为,同时在以下示例中完全按预期工作:
> (list-minus '(1 2 3 4 5) '(x 2 4 m))
=> '(1 3 5)
问题2:如何修复list-minus代码,还是需要从头开始?
问题 3: 在上面的第一行代码中,我必须“扩展”car 和 cdr 以确保 prod 函数不会引发错误。我做的是标准把戏吗?我不确定我是否理解它为什么会有所作为(我只是试了一下,因为我有预感它可能会起作用)。
免责声明:我不是程序员。我正在尝试学习函数式编程,以此来测试各种(数学)猜想并编译一些示例。除了在 DrRacket 和旧的 TI-83 计算器上完成的一些非常愚蠢的小代码之外,我完全没有编写代码的经验。话虽如此,可能有必要为我“简化”您的答案。
抱歉啰嗦了,感谢您的宝贵时间!
【问题讨论】:
-
(eq? '(1) '(1)) ; ==> #f而(equal? '(1) '(1)) ; ==> #t