我试图在Scheme中编写一个函数,我接受一个列表并返回所有不同的紊乱(在下面看看定义)作为列表列表
derangement :没有项目与原始列表位于同一位置的列表 例如:'(a b c) - > “(驾驶室)
任何帮助表示赞赏!
答案 0 :(得分:2)
计算输入列表的所有排列,然后过滤掉与输入列表位于同一位置的元素。如果您需要更多详细信息,请发表评论。
定义(或者可能已经定义了?好的练习,无论如何)一个名为filter
的过程,它将过程p
和列表l
作为第一个参数作为其第二个参数。返回一个列表,其中仅包含(p l)
返回真值的值。
定义一个程序derangement?
,用于测试列表l1
是否是l2
的紊乱。与filter
配对时,这将非常方便。
答案 1 :(得分:0)
最明显的解决方案是这样的:
(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)))))))))))