如何在mathematica中找到包含重复项的两个列表的交集?
所以,如果我有这个:
list1 = {1, 1, 3, 4, 5, 6, 6, 6, 7, 7, 10, 11, 11};
list2 = {1, 1, 4, 5, 5, 6, 6, 7, 7, 8, 11, 11, 13, 14};
我希望它能归还:
IntersectionIncludingDuplicates[list1, list2] = {1, 1, 4, 5, 6, 6, 7, 7, 11, 11}
感谢您的帮助!
答案 0 :(得分:1)
这是一种方式:
Catenate@KeyValueMap[ConstantArray]@
MapThread[Min, KeyIntersection[Counts /@ {list1, list2}]]
打破它:
Counts
)KeyIntersection
)MapThread
,Min
)并多次复制给定元素(ConstantArray
)答案 1 :(得分:0)
编辑:修复并测试..
您可以使用常规Intersection
,然后使用Count
,例如
ConstantArray[#, Min[Count[list1, #], Count[list2, #]]] & /@
Intersection[list1, list2] // Flatten
{1,1,4,5,6,6,7,7,11,11}
以函数形式推广以采用任意数量的列表:
IntersectionIncludingDuplicates[lists__List] :=
ConstantArray[#,
Function[{v}, Min @@ (Count[#, v] & /@ {lists})]@#] & /@
Intersection[lists] // Flatten
IntersectionIncludingDuplicates[list1, list2]
{1,1,4,5,6,6,7,7,11,11}
答案 2 :(得分:0)
简单的代码来理解。假设输入列表已排序。
list1 = {1, 1, 3, 4, 5, 6, 6, 6, 7, 7, 10, 11, 11};
list2 = {1, 1, 4, 5, 5, 6, 6, 7, 7, 8, 11, 11, 13, 14};
IntersectionIncludingDuplicates[list1_, list2_] := Module[
{out = {}, i = j = 1},
While[i <= Length[list1] && j <= Length[list2],
If[list1[[i]] == list2[[j]],
AppendTo[out, list1[[i]]];
i++; j++,
If[list1[[i]] < list2[[j]], i++, j++]]];
out]
IntersectionIncludingDuplicates[list1, list2]
{1,1,4,5,6,6,7,7,11,11}