【发布时间】:2011-05-02 04:19:58
【问题描述】:
我试图在 Scheme 中编写一个函数,我接受一个列表并将所有不同的错位(请看下面的定义)作为列表列表返回
混乱:没有项目与原始列表在同一位置的列表 例如:'(a b c) -> '(cab)
感谢任何帮助!
【问题讨论】:
标签: list function functional-programming scheme
我试图在 Scheme 中编写一个函数,我接受一个列表并将所有不同的错位(请看下面的定义)作为列表列表返回
混乱:没有项目与原始列表在同一位置的列表 例如:'(a b c) -> '(cab)
感谢任何帮助!
【问题讨论】:
标签: list function functional-programming scheme
计算输入列表的所有排列,然后过滤掉与输入列表具有相同位置的元素的排列。如果您需要更多详细信息,请发表评论。
定义(或者它可能已经定义了?很好的练习,无论如何)一个名为filter 的过程,它的第一个参数是一个过程p,第二个参数是一个列表l。返回一个仅包含 (p l) 为其返回真值的值的列表。
定义一个过程derangement? 来测试列表l1 是否是l2 的混乱。这在与filter 配对时会很方便。
【讨论】:
cons 单元格,其中您要保留的元素为car,并在列表的其余部分中递归的结果为cdr。如果您不想保留该元素,请不要创建新的cons。
最明显的解决方案是这样的:
(define filtered-permutations
(lambda (lst)
(filter
(lambda (permuted-list)
(deranged? permuted-list lst))
(permute lst))))
由于混乱的数量大大低于排列的数量,但是,这不是很有效。这是一个解决方案,它主要避免生成不是混乱的排列,但为了简单起见,确实使用了一次filter:
(define deranged?
(lambda (lst1 lst2)
(if (null? lst1)
#t
(if (eq? (car lst1) (car lst2))
#f
(deranged? (cdr lst1) (cdr lst2))))))
(define derange
(lambda (lst)
(if (< (length lst) 2)
;; a list of zero or one elements can not be deranged
'()
(permute-helper lst lst))))
(define derange-helper
(lambda (lst template)
(if (= 2 (length lst))
(let ((one (car lst))
(two (cadr lst)))
(filter
(lambda (x)
(deranged? x template))
(list (list one two) (list two one))))
(let ((anchor (car template)))
(let loop ((todo lst)
(done '())
(result '()))
(if (null? todo)
result
(let ((item (car todo)))
(if (eq? item anchor)
;; this permutation would not be a derangement
(loop (cdr todo)
(cons item done)
result)
(let ((permutations
(map
(lambda (x)
(cons item x))
(derange-helper (append (cdr todo) done)
(cdr template)))))
(loop (cdr todo)
(cons item done)
(append result permutations)))))))))))
【讨论】: