来自多个列表的组元素

时间:2015-04-04 11:17:56

标签: java list groovy

我有以下数据结构:

enter image description here

基本上我在这里有一个列表,其中包含其他列表(它们的大小可以是任意的,在我的情况下,所有4个列表的大小都是2)。我必须分组,以便具有相同元素的列表进入一个列表(可能不是最好的配方,但我不能更好地制定它)。在我的情况下,结果应如下: [72, 83, 127][110, 119]

例如,如果第三个子列表包含元素[83, 127, 55, 22],则结果应如下所示:[72, 83, 127, 55, 22][110, 119]。 (所以我必须包括所有子列表元素。)

我如何在Java或Groovy中做这样的事情?

2 个答案:

答案 0 :(得分:1)

由于您必须处理整个列表,因此一个不错的选择是利用groovy collection的inject方法(添加println来显示步骤):

def values = [[72, 83], [72, 127], [83, 127], [110, 119]]

def result = values.inject([], { res, value -> 
    println "res = $res | value = $value"
    def found = res.find {
        if (it.intersect(value)) {
            it.addAll(value - it)
            true
        }
    }

    if (!found) {
        res << value
    }

    res
 })

 println result

 assert [[72, 83, 127], [110, 119]] == result

那样:

res = [] | value = [72, 83]
res = [[72, 83]] | value = [72, 127]
res = [[72, 83, 127]] | value = [83, 127]
res = [[72, 83, 127]] | value = [110, 119]
[[72, 83, 127], [110, 119]]

编辑:上述解决方案在某些情况下效果不佳,即

def values = [[72, 83], [72, 127], [83, 127], [110, 119], [47, 56], [56, 72]]

产量

[[72, 83, 127, 56], [110, 119], [47, 56]]

如果列表被排序,它会产生(我认为这是正确的解决方案)

[[47, 56, 72, 83, 127], [110, 119]]

编辑(2):解决上一个问题的更好解决方案(即列表共享元素包含多个结果列表):

def values = [[72, 83], [72, 127], [83, 127], [110, 119], [120, 121], [121, 127]]

def result = values.inject([], { res, value -> 
    println "res = $res | value = $value"
    def found = res.findAll { it.intersect(value) }
    println "  -> found = $found"

    if (!found) {
        res << value
    } else {
        res.removeAll(found)
        def merged = found.collect({ it + value as Set }).flatten() as Set
        println "  -> merged = $merged"
        res << merged
    }

    println "  => res = $res"
    res
})

答案 1 :(得分:0)

这是使用maps的java实现。首先,我们将ArrayList转换为映射,即key = integerInList + value = NoOfOccurrence。然后我们只搜索地图中的每个元素,如果元素有多于1个出现,那么我们只需添加到相应的组(Set)。

public static void find() {
    //Input Data
    ArrayList<List<Integer>> list1 = new ArrayList<>();
    list1.add(Arrays.<Integer>asList(72, 83));
    list1.add(Arrays.<Integer>asList(72, 127));
    list1.add(Arrays.<Integer>asList(83, 127));
    list1.add(Arrays.<Integer>asList(110, 119));

    Map<Integer, Integer> map = new HashMap<>();

    //Convert Input Data to Map
    for (List<Integer> integers : list1) {
        for (Integer integer : integers) {
            int integer1=1;
            if (map.containsKey(integer)) {
                integer1 += map.get(integer);
            }
            map.put(integer, integer1);
        }
    }

    Set<Integer> group1 = new HashSet<>();
    Set<Integer> group2 = new HashSet<>();
    //find and build groups
    for (List<Integer> integers : list1) {
        boolean found = false;
        for (Integer integer : integers) {
            if (map.containsKey(integer)) {
                if (map.get(integer) > 1) {
                    found = true;
                    break;
                }
            }
        }
        if (found) {
            group1.addAll(integers);
        } else {
            group2.addAll(integers);
        }
    }

    System.out.println("group1 = " + group1);
    System.out.println("group2 = " + group2);
}