Solution
我最后使用了以下执行办法:对David Fletcher的答复稍加修改:
isect :: Eq a => [a] -> [a] -> [a]
isect [] = const [] -- don t bother testing against an empty list
isect xs = catMaybes . diagonal . map matches
where matches y = [if x == y then Just x else Nothing | x <- xs]
可以用nub来补充,以过滤重复:
isectUniq :: Eq a => [a] -> [a] -> [a]
isectUniq xs = nub . isect xs
Explanation
<代码>isection xs = catMaybes 。 地图匹配
。 3 ! 0将代表ys ! 3
with xs ! 0
,如果这些数值有所不同,将改为Nothing
。 如果这些数值相同,则该数值为Just
。
diagonals
takes a list of lists and returns a list of lists where the nth output list contains an element each from the first n lists. Another way to conceptualise it is that (diagonals . map matches) ys !! n
contains comparisons between elements whose indices in xs
and ys
sum to n
.
diagonal
is simply a flat version of diagonals
(diagonal = concat diagonals
)
因此, (diagonal .mapcompes) ys/code>是xs
和s
各要素之间的比较清单,其中各要素大致按以下各要素的指数的总和加以比较:ys
x
;这意味着早期要素与较后各项要素相比,与中间要素相比,各部分具有相同的优先权。
(cat Maybes . diagonal .mapcompes) ys
is a list of only the elements which are in both list, where the elements are around打上了两个要素的比较指数的总和。
Note
(diagonal . map (catMaybes . matches)) ys
does not work: catMaybes . matches
only yields when it finds a match, instead of also yielding Nothing
on no match, so the interleaving does nothing to distribute the work.
相比之下,在选定的解决办法中,Nothing
和Just
的数值通过>diagonal
,意味着该方案在寻找多个不同要素,而不是等待一个因素之后,将其注意力分开;而如果在环绕之前删除<>Nothing的数值,则该方案可能花费太多的时间等待对某一特定要素进行无果的搜索以取得成功。
因此,我们会遇到与原始问题相同的问题:虽然一个因素与另一个清单中的任何内容不相称,但方案将保持不变;而所选择的解决办法将只剩下来,而两个清单中的任何内容都找不到对应办法。