Java n个列表的所有组合的交集

Java n个列表的所有组合的交集,java,arraylist,combinations,set-intersection,Java,Arraylist,Combinations,Set Intersection,给定一个大于3的ArrayList的ArrayList ArrayList list=new ArrayLists(); 我想得到3个唯一的子列表,找到它们的交集,然后对所有可能的组合重复这个过程。下面是伪代码 public void generateIntersections(数组列表){ 如果(lists.size()>3){ int n=lists.size(); //理论上,“组合数”是错误的,我知道 int numberofcombines=n!/(3!(n-3); while(组合

给定一个大于3的ArrayList的ArrayList

ArrayList list=new ArrayLists();
我想得到3个唯一的子列表,找到它们的交集,然后对所有可能的组合重复这个过程。下面是伪代码

public void generateIntersections(数组列表){
如果(lists.size()>3){
int n=lists.size();
//理论上,“组合数”是错误的,我知道
int numberofcombines=n!/(3!(n-3);
while(组合数){
//独特项目
ArrayList列表1=列表。获取(?);
ArrayList列表2=列表。获取(?);
ArrayList list 3=列表。获取(?);
集合=交叉点(列表1、列表2、列表3);
}
}
}
我对这个问题感到困惑,因为我不知道如何在迭代时正确跟踪三个计数器。在这种特殊情况下,正确地实现组合而不是排列的概念进一步阻碍了我

我尝试了很多方法,但在每一种情况下,我的代码都很快变得毫无意义。我想我缺少一些特别的技巧。可能涉及哈希集?

Java 7中交叉点的交叉点映射 处理原始列表的三个步骤:首先为每个元素收集交叉点地图
map
,然后为该地图收集交叉点地图
map
,然后将较大的交叉点集附加到较小的交叉点集(如果它们相交)

原始列表
列表

1-交叉口地图
地图

2-交叉路口地图
地图

3-将较大交叉点集附加到较小交叉点集(如果它们相交)后的交叉点地图:

Lists: [0, 1, 2] contain elements: [2, 4]
Lists: [0, 1] contain elements: [2, 3, 4, 5]
Lists: [0, 2] contain elements: [1, 2, 4, 6]
Lists: [1, 2] contain elements: [2, 4, 7]

Java 7代码:

List List=Arrays.asList(
数组.asList(1,2,6,5,4,3),
数组.asList(3,7,2,9,5,4),
asList(2,6,7,1,4));
//交叉口地图:
//列表的关键元素,
//值-列表的索引集,
//即该元素出现的位置
Map map1=新树映射();
对于(int i=0;i
//中间输出
对于(Map.Entry:map1.entrySet())
System.out.println(“元素:”+entry.getKey()
+在列表中:“+entry.getValue());
//交叉口地图的自定义比较器
比较器比较器=新比较器(){
@凌驾
公共整数比较(集合o1,集合o2){
//将相等的交点分组
如果(o1.containsAll(o2)和&o2.containsAll(o1))返回0;
//按相反顺序比较交叉口的数量
int val=Integer.compare(o2.size(),o1.size());
如果(val!=0)返回val;
//如果大小相等,请比较哈希代码
返回整数.compare(o1.hashCode(),o2.hashCode());
}
};
//交叉口的交叉口地图:
//key-列表的索引集
//元素的值集
TreeMap map2=新的TreeMap(比较);
对于(Map.Entry:map1.entrySet()){
//相交元素集
Set key=entry.getValue();
//过滤出独特的元素
如果(key.size()==1)继续;
//拉出相交元素集
设置值=map2。删除(键);
//如果它不存在,就创建它
如果(value==null)value=newtreeset();
//添加当前元素
value.add(entry.getKey());
//放在地图上
map2.put(键、值);
}
//中间输出
对于(Map.Entry:map2.entrySet())
System.out.println(“列表:”+entry.getKey()
+包含元素:“+entry.getValue());
//将较大的交点集附加到
//如果相交,则设置较小的交点
对于(Map.Entry:map2.entrySet()){
//对于每个输入进程,其他进程的值
//交叉口数量较少的入口
Map tailMap=map2.tailMap(entry.getKey(),false);
对于(Map.Entry-other:tailMap.entrySet())
//如果当前条目的交点集包含
//另一条记录集的所有交点
if(entry.getKey().containsAll(other.getKey()))
//然后添加所有相交的元素
//将当前条目转换为其他条目
other.getValue().addAll(entry.getValue());
}
//最终输出
对于(Map.Entry:map2.entrySet())
System.out.println(“列表:”+entry.getKey()
+包含元素:“+entry.getValue());

另见:

Element: 1 is in lists: [0, 2]
Element: 2 is in lists: [0, 1, 2]
Element: 3 is in lists: [0, 1]
Element: 4 is in lists: [0, 1, 2]
Element: 5 is in lists: [0, 1]
Element: 6 is in lists: [0, 2]
Element: 7 is in lists: [1, 2]
Element: 9 is in lists: [1]
Lists: [0, 1, 2] contain elements: [2, 4]
Lists: [0, 1] contain elements: [3, 5]
Lists: [0, 2] contain elements: [1, 6]
Lists: [1, 2] contain elements: [7]
Lists: [0, 1, 2] contain elements: [2, 4]
Lists: [0, 1] contain elements: [2, 3, 4, 5]
Lists: [0, 2] contain elements: [1, 2, 4, 6]
Lists: [1, 2] contain elements: [2, 4, 7]