Java 如果我有一份清单<;设置<;整数>&燃气轮机;删除任何其他集合的子集的快速方法是什么?

Java 如果我有一份清单<;设置<;整数>&燃气轮机;删除任何其他集合的子集的快速方法是什么?,java,Java,我有一个相当大的整数集列表(Java)。我想删除列表中所有集合,这些集合是列表中任何其他集合的子集。如果两组相同,则最终列表中只应保留一组 显然,要做的事情是遍历我的列表,并对照调用某种子集检查方法的所有其他元素检查每个元素。但这是非常低效的。我能做些更好的事吗 我目前正在使用hashset和ArrayList,但是如果相关的话,我可以很容易地更改它 ArrayList可以是任何类型的集合,因此我想我可能可以对集合做一些处理,以至少避免等价的整数集合。这是一种方法 public void met

我有一个相当大的整数集列表(Java)。我想删除列表中所有集合,这些集合是列表中任何其他集合的子集。如果两组相同,则最终列表中只应保留一组

显然,要做的事情是遍历我的列表,并对照调用某种子集检查方法的所有其他元素检查每个元素。但这是非常低效的。我能做些更好的事吗

我目前正在使用hashset和ArrayList,但是如果相关的话,我可以很容易地更改它


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[]检查子集会更便宜吗