简体   繁体   English

Java以递归方式从Arraylist的Arraylist中删除元素

[英]Java recursively remove elements from Arraylist of Arraylists

I'm writing a software in which I have to deal with ArrayList<ArrayList<Integer>> . 我正在编写一个必须处理ArrayList<ArrayList<Integer>> What I have to do is to remove duplicates in the sublists, starting from the shortest one and removing those values from the other sublists if they exist, and so on iteratively since there are no more duplicates. 我要做的是从最短的子列表中删除子列表中的重复项,然后从其他子列表中删除这些值(如果它们存在的话),如此反复进行,因为不再有重复项。 For example, my original list of lists is: 例如,我原始的列表列表是:

[[4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31], 
[26, 27, 28, 29, 30, 31], 
[11, 12, 13, 14], 
[13, 14], [9, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]]

and the final result I want is the following: 我想要的最终结果如下:

[[4, 5, 6, 7, 8, 15, 16, 17, 18, 19, 20], 
[26, 27, 28, 29, 30, 31], 
[11, 12], 
[13, 14], [9, 22, 23, 24, 25]]

From the original list I see that the sub list [13,14] is the shortest and these values are not unique in the main list, then I remove them from all the other sublists: 从原始列表中,我看到子列表[13,14]是最短的,并且这些值在主列表中不是唯一的,然后从所有其他子列表中将它们删除:

[[4, 5, 6, 7, 8, 9, 11, 12, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31], 
[26, 27, 28, 29, 30, 31], 
[11, 12], 
[13, 14], [9, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]]

Now the next shortest sublist is [11, 12] and then I remove these two values from all the other lists and so on. 现在,下一个最短的子列表是[11, 12] ,然后从所有其他列表中删除这两个值,依此类推。

I really have no idea how to write recursive code, any ideas? 我真的不知道如何编写递归代码,有什么想法吗?

EDIT: the number of sublists is not constant. 编辑:子列表的数量不是恒定的。

public class Test6 {

    public static void main(String[] args) throws Exception {

        Integer[] list1 = { 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };
        Integer[] list2 = { 26, 27, 28, 29, 30, 31 };
        Integer[] list3 = { 11, 12, 13, 14 };
        Integer[] list4 = { 13, 14 };
        Integer[] list5 = { 9, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 };

        ArrayList<ArrayList<Integer>> main = new ArrayList<ArrayList<Integer>>();
        main.add(new ArrayList(Arrays.asList(list1)));
        main.add(new ArrayList(Arrays.asList(list2)));
        main.add(new ArrayList(Arrays.asList(list3)));
        main.add(new ArrayList(Arrays.asList(list4)));
        main.add(new ArrayList(Arrays.asList(list5)));

        for (ArrayList<Integer> list : main) {
            System.out.println(list);
        }

        removeDuplicates(main);

        System.out.println("________________________________________");

        for (ArrayList<Integer> list : main) {
            System.out.println(list);
        }

    }

    private static void removeDuplicates(ArrayList<ArrayList<Integer>> main) {
        // Sort the lists based on their size
        Collections.sort(main, new Comparator<ArrayList<Integer>>() {

            @Override
            public int compare(ArrayList<Integer> o1, ArrayList<Integer> o2) {
                return Integer.valueOf(o2.size()).compareTo(Integer.valueOf(o1.size()));
            }
        });

        for (ArrayList<Integer> list1 : main) {
            for (ArrayList<Integer> list2 : main) {
                if (list2 != list1) {
                    removeDuplicateNumbers(list1, list2);
                }
            }
        }
    }

    private static void removeDuplicateNumbers(ArrayList<Integer> list1, ArrayList<Integer> list2) {
        for (Integer number : list2) {
            list1.remove(number);
        }
    }
}

I wrote this pseudo code in around 30 minutes without the ability to test it so let me know if there are mistakes. 我在大约30分钟的时间内编写了此伪代码,但是没有测试能力,所以请告诉我是否有错误。 You don't really need recursion, but if you are inclined to do recursion you can kinda do it like this (except this isn't the best example of recursion). 您实际上并不需要递归,但是如果您打算进行递归,则可以这样进行(除非这不是递归的最佳示例)。 The idea is to make a copy of the source array. 这个想法是复制源数组。 From that copy, find the shortest sub-array and remove all duplicates from the rest of the sub-arrays in the copy. 从该副本中找到最短的子数组,然后从副本中其余子数组中删除所有重复项。 Lastly, place the shortest into the return array, and call the function again, using the modified temp array, and the newly updated return array. 最后,将最短的数组放入返回数组,并使用修改后的临时数组和新近更新的返回数组再次调用该函数。

tempArray = actualArray;
returnArray = new Array<Array<int>();
filterList(tempArray, returnArray);

void filterList(<Array<Array<int>> temp, Array<Array<int>> returnArray){
    // If we're done with recursion
    if (temp.isEmpty)
        return;

    // Arbitrarily start with a shortest array. Starting empty would result in staying empty
    Array<int> shortestArray = temp[0];

    // Find our shortest array so we can check list contents.
    for(Array<int> subArray in temp){
        if(subArray.length < shortestArray.length){
            shortestArray = subArray;
        }
    }

    // remove shortest from temp so we can work on the rest of the list.
    temp.remove(shortestArray);

    // Loop through the array and remove all instances of repeated items
    for(i = 0; i < shortestArray.length; i++){
        for(Array<int> subArray in temp){
            if(subArray.contains(shortestArray[i])){
                subArray.remove(shortestArray[i]);
            }
        }
    }

    // Place shortest into return, and then enter recursion.
    returnArray.add(shortestArray);
    filterList(temp, returnArray);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM