![](/img/trans.png)
[英]Need to remove elements from an ArrayList of ArrayLists<Double>
[英]Java recursively remove elements from Arraylist of Arraylists
我正在编写一个必须处理ArrayList<ArrayList<Integer>>
。 我要做的是从最短的子列表中删除子列表中的重复项,然后从其他子列表中删除这些值(如果它们存在的话),如此反复进行,因为不再有重复项。 例如,我原始的列表列表是:
[[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]]
我想要的最终结果如下:
[[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]]
从原始列表中,我看到子列表[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]]
现在,下一个最短的子列表是[11, 12]
,然后从所有其他列表中删除这两个值,依此类推。
我真的不知道如何编写递归代码,有什么想法吗?
编辑:子列表的数量不是恒定的。
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);
}
}
}
我在大约30分钟的时间内编写了此伪代码,但是没有测试能力,所以请告诉我是否有错误。 您实际上并不需要递归,但是如果您打算进行递归,则可以这样进行(除非这不是递归的最佳示例)。 这个想法是复制源数组。 从该副本中找到最短的子数组,然后从副本中其余子数组中删除所有重复项。 最后,将最短的数组放入返回数组,并使用修改后的临时数组和新近更新的返回数组再次调用该函数。
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.