我正在学习Jjava,并且在ArrayLists上发现了一个有趣的练习。目的是编写一个函数int
,该函数接受参数partition()
和参数list
并返回子列表的列表,其中每个子列表的最大值为{{1} }元素。
例如:
size
应该返回size
,partition([1,2,3,4,5], 2)
应该返回[ [1,2], [3,4], [5] ]
,partition([1,2,3,4,5], 3)
应该返回[ [1,2,3], [4,5] ]
。我这样做了,但是只有在参数partition([1,2,3,4,5], 1)
等于[ [1], [2], [3], [4], [5] ]
并且我想在所有情况下都这样做时,它才有效,如果有人可以帮助我,我很努力。 / p>
size
答案 0 :(得分:0)
您可以使用subList方法。
public ArrayList<ArrayList> partition(List<Integer> li, int n) {
ArrayList<ArrayList> al = new ArrayList();
int start = 0;
int i=n;
for(; i<li.size(); i+=n){
List<Integer> lis = li.subList(start, i);
ArrayList<Integer> list = new ArrayList<>();
list.addAll(lis);
al.add(list);
start = i;
}
if(i >= li.size()){
List<Integer> lis = li.subList(start, li.size());
ArrayList<Integer> list = new ArrayList<>();
list.addAll(lis);
al.add(list);
}
return al;
}
答案 1 :(得分:0)
我试图了解您的解决方案,但不幸的是我没有理解。您的外部循环是错误的:最外部的循环一定是从0到列表的大小,而不是分区的大小。
下一件事是您的最内层循环。每次您进入内部时,都要创建一个新列表,向其中添加一个元素,然后将此列表添加到结果中。这没有任何意义。您最有可能想要这样的东西(中间循环的主体)
List<Integer> list = new ArrayList<Integer>(n);
for (...) {
...
int b = l.get(j);
list.add(b);
...
}
al.add(list);
但是当您引入了第三个循环时,它仍然不起作用,在这里绝对没有必要。为了使您的解决方案可靠,您仅需要2个循环(第一个-遍历整个列表,第二个遍历当前分区:
public static List<List<Integer>> partition(List<Integer> l, int n) {
List<List<Integer>> al = new ArrayList<>();
for (int i = 0; i < l.size(); i += n) {
List<Integer> list = new ArrayList<>();
for (int j = i; j < i + n && j < l.size(); j++) {
list.add(l.get(j));
}
al.add(list);
}
return al;
}
看一下我选择的边界:外循环从0到列表大小,步长为分区大小,而内循环从外循环的当前索引到分区大小或列表大小,以先到者为准。
有一个更简单的解决方案:
private static List<List<?>> partition(List<?> list, int size) {
var result = new ArrayList<List<?>>();
for (int i = 0; i < list.size(); i += size) {
result.add(new ArrayList<>(list.subList(i, Math.min(i + size, list.size()))));
}
return result;
}
这是一种通用方法,您可以传递任何元素的列表(不仅仅是整数)并获得分区结果。这又是一个循环,该循环从0到具有分区大小步长的列表大小,并且每次都根据分区大小或原始元素的子列表(如果少于完整分区的话)获得剩余列表的子列表。
此外,作为旁注。使用接口(List
)而不是实现(ArrayList
)和通用类型(ArrayList<>()
,List<Integer>()
,List<?>
而不是原始代码来查看我的代码类型(ArrayList()
)