Java 如果我有一份清单<;设置<;整数>&燃气轮机;删除任何其他集合的子集的快速方法是什么?
我有一个相当大的整数集列表(Java)。我想删除列表中所有集合,这些集合是列表中任何其他集合的子集。如果两组相同,则最终列表中只应保留一组 显然,要做的事情是遍历我的列表,并对照调用某种子集检查方法的所有其他元素检查每个元素。但这是非常低效的。我能做些更好的事吗 我目前正在使用hashset和ArrayList,但是如果相关的话,我可以很容易地更改它Java 如果我有一份清单<;设置<;整数>&燃气轮机;删除任何其他集合的子集的快速方法是什么?,java,Java,我有一个相当大的整数集列表(Java)。我想删除列表中所有集合,这些集合是列表中任何其他集合的子集。如果两组相同,则最终列表中只应保留一组 显然,要做的事情是遍历我的列表,并对照调用某种子集检查方法的所有其他元素检查每个元素。但这是非常低效的。我能做些更好的事吗 我目前正在使用hashset和ArrayList,但是如果相关的话,我可以很容易地更改它 ArrayList可以是任何类型的集合,因此我想我可能可以对集合做一些处理,以至少避免等价的整数集合。这是一种方法 public void met
ArrayList可以是任何类型的集合,因此我想我可能可以对集合做一些处理,以至少避免等价的整数集合。这是一种方法
public void method() {
List<Set<Integer>> list = new ArrayList<>();
Set<Integer> a = new HashSet<>();
a.add(1);
a.add(2);
a.add(3);
a.add(4);
a.add(5);
Set<Integer> b = new HashSet<>();
b.add(1);
b.add(2);
b.add(3);
list.add(a);
list.add(b);
System.out.println("Original :" + list);
class SizeComarator implements Comparator<Set<?>> {
@Override
public int compare(Set<?> o1, Set<?> o2) {
return Integer.valueOf(o1.size()).compareTo(o2.size());
}
}
Collections.sort(list, new SizeComarator());
System.out.println("Sorted :" + list);
List<Set<Integer>> result = new ArrayList<>();
for(int i=0; i<list.size(); i++) {
Set<Integer> prev = list.get(i);
boolean flag = false;
for(int j=i+1; j<list.size(); j++) {
if(list.get(j).containsAll(prev))
flag = true;
}
if(!flag)
result.add(prev);
}
System.out.println("Reduced :" + result);
}
public void方法(){
列表=新的ArrayList();
Set a=新的HashSet();
a、 增加(1);
a、 增加(2);
a、 增加(3);
a、 增加(4);
a、 增加(5);
Set b=新的HashSet();
b、 增加(1);
b、 增加(2);
b、 增加(3);
列表.添加(a);
列表.添加(b);
系统输出打印项次(“原件:+列表);
类SizeCorator实现Comparator这是我根据需求尝试的:
- 如果两套相同,只保留一套
- 删除任何集合的子集合
- 此外,输入数据的处理方式也具有灵活性
输入数据格式被修改为使用List
而不是List
。原因是在此过程中整数集没有改变,int[]
可能会执行得更好,我发现它使用起来很简单。我创建了一个围绕输入整数集数据的包装器,名为IntegerSet
,并使用它
代码如下:
import java.util.*;
import java.util.stream.*;
public class IntegerSetProcess {
public static void main(String[] args) {
// Input data
List<IntegerSet> inputList =
Arrays.asList(new IntegerSet(new int [] {11}),
new IntegerSet(new int [] {12, 555}),
new IntegerSet(new int [] {2, 333, 555, 9, 144, 89}),
new IntegerSet(new int [] {12}),
new IntegerSet(new int [] {12, 3, 555, 90, 42, 789, 15000}),
new IntegerSet(new int [] {2, 555, 9, 89, 333, 144}),
new IntegerSet(new int [] {555, 12}),
new IntegerSet(new int [] {222, 12, 41320, 0, 769942}),
new IntegerSet(new int [] {910, 77}));
// Distinct IntegerSets
List<IntegerSet> distinctList =
inputList.stream()
.distinct()
.sorted()
.collect(Collectors.toList());
// Filter subsets to get result
List<IntegerSet> resultList = doSubsetFiltering(distinctList);
// Result data in original form (optional)
resultList.stream()
.forEach(e -> System.out.println(Arrays.toString(e.getOriginal())));
}
/*
* Takes the input List<IntegerSet> and removes all the IntegerSets with
* elements as subset in any other IntegerSet.
*/
private static List<IntegerSet> doSubsetFiltering(List<IntegerSet> listIs) {
List<IntegerSet> removedIs = new ArrayList<>();
OUTER_LOOP: // size-1, the last element is not iterated
for (int i = 0; i < listIs.size()-1; i++) {
IntegerSet thisIs = listIs.get(i);
INNER_LOOP: // i+1, the checking starts from the next IntegerSet
for (int j = i+1; j < listIs.size(); j++) {
IntegerSet nextIs = listIs.get(j);
if (isSubset(thisIs.getData(), nextIs.getData())) {
// To remove thisIs set as it is a subset of isNext
removedIs.add(thisIs);
break INNER_LOOP;
}
} // inner-for-loop
} // outer for-loop
listIs.removeAll(removedIs);
return listIs;
}
// Returns true if the input array thisIs has all its elements in nextIs.
public static boolean isSubset(int[] thisIs, int[] nextIs) {
for(int i : thisIs) {
if (Arrays.binarySearch(nextIs, i) < 0) {
return false;
}
}
return true;
}
}
import java.util.*;
import java.util.stream.*;
public class IntegerSet implements Comparable<IntegerSet> {
private int[] data;
private int[] original;
public IntegerSet(int[] intput) {
original = IntStream.of(intput).toArray();
data = intput;
Arrays.sort(data);
}
public int[] getData() {
return data;
}
public int[] getOriginal() {
return original;
}
@Override
public String toString() {
return Arrays.toString(data);
}
@Override
public boolean equals(Object obj) {
IntegerSet is = (IntegerSet) obj;
if (Arrays.equals(data, is.getData())) {
return true;
}
return false;
}
@Override
public int hashCode() {
return data.length;
}
@Override
public int compareTo(IntegerSet is) {
return Integer.valueOf(data.length).compareTo(is.getData().length);
}
}
import java.util.*;
导入java.util.stream.*;
公共类IntegerSetProcess{
公共静态void main(字符串[]args){
//输入数据
列表输入列表=
asList(新整数集(新int[]{11}),
新整数集(新整数[]{12555}),
新的整数集(新的int[]{2,333,555,9,144,89}),
新整数集(新整数[]{12}),
新的整数集(新的整数[]{12,3,555,90,42,789,15000}),
新的整数集(新的int[]{2555,9,89333144}),
新整数集(新整数[]{555,12}),
新的整数集(新的int[]{222,1241320,0769942}),
新的整数集(新的int[]{910,77});
//不同整数集
列表区列表=
inputList.stream()
.distinct()
.已排序()
.collect(Collectors.toList());
//筛选子集以获得结果
列表结果列表=doSubsetFiltering(distinctList);
//原始形式的结果数据(可选)
resultList.stream()
.forEach(e->System.out.println(Arrays.toString(e.getOriginal()));
}
/*
*获取输入列表并删除所有带有
*元素作为任何其他整数集中的子集。
*/
私有静态列表doSubsetFiltering(列表listIs){
List removedIs=new ArrayList();
OUTER_LOOP://size-1,最后一个元素不迭代
对于(inti=0;i
看看lambda表达式(来自Java 8的新概念).正如你所说,你不需要iterate@Davide我认为OP与运行时性能有关。一种可能的优化方法是按大小对集合进行排序,避免检查较大集合是否是较小集合的子集。如果集合是HashSet
s,则确定一个集合是否是另一个集合的子集将变为O(s),而不是更糟糕的事情,其中“s”是较小集合的大小。如果我们将集合转换为排序的int[],您认为使用两个集合或两个排序的int[]检查子集会更便宜吗