我正在学习Jjava,我在ArrayLists上发现了一个有趣的练习。目的是编写一个函数partition()
,该函数接受一个参数列表
和一个参数大小
,并返回一个子列表列表,其中每个子列表都有最大的大小
元素。
例如:
分区([1,2,3,4,5]
, 2) 应返回 [ [1,2], [3,4], [5] ],
分区([1,2,3,4,5]
, 3) 应返回 [ [1,2,3], [4,5] ],
分区([1,2,3,4,5]
, 1) 应返回 [ [1], [2], [3], [4], [5] ]。
我这样做了,但只有当参数size
等于1
public static void main(String[] args) {
Apside t = new Apside();
ArrayList<Integer> a = new ArrayList<Integer>();
a.add(1);
a.add(2);
a.add(3);
a.add(4);
System.out.println(t.partition(a, 1));
}
public ArrayList<ArrayList> partition(ArrayList<Integer> l, int n) {
ArrayList<ArrayList> al = new ArrayList();
for (int i = 0; i < n; i++) {
for (int j = 0; j < l.size(); j++) {
for(int k =0; k<n; k++){
ArrayList<Integer> list = new ArrayList(n);
int b = l.get(j);
list.add(b);
al.add(list);
}
}
}
return al;
}
我试图理解你的解决方案,但不幸的是,我不明白。你的外部循环是错误的:最外部的循环肯定应该是从0到列表的大小,而不是分区的大小。
接下来就是你最内在的循环。每次你在里面创建一个新列表时,向其中添加一个元素,并将此列表添加到结果中。这没有任何意义。很可能你想要这样的东西(中间循环的主体)
List<Integer> list = new ArrayList<Integer>(n);
for (...) {
...
int b = l.get(j);
list.add(b);
...
}
al.add(list);
但是它仍然不起作用,因为你引入了第三个循环,这在这里肯定是不必要的。为了使您的解决方案可靠,您只需要两个循环(第一个是遍历整个列表,第二个是遍历当前分区:
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 到具有分区大小步骤的列表大小,每次都会根据分区大小获取原始列表的子列表,或者如果分区小于完整,则只获取剩余元素。
此外,作为一个旁注。看看我使用接口(< code>List)而不是实现(< code>ArrayList)并使用泛型类型(< code>ArrayList)的代码
您可以使用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;
}
我有一个列表,我想创建一个名为的扩展。 我不想覆盖,因此不能使用append、extend或insert。我想知道是否有一个快速的方法来完成这项工作(比使用理解列表或Deep.copy更快)
问题内容: 我有一个ArrayList,我想将其分成n个大小的较小列表,并对每个列表执行一个操作。我目前这样做的方法是 用Java中的ArrayLists实现(任何伪代码都可以) 其中A是列表,n是所需列表的大小 我认为在处理相当大的列表(最大为100万个)时,这种方法会花费太多时间,因此我试图找出哪种方法更有效。 问题答案: 您需要做一些利用List.subList(int,int)视图的事情,
问题内容: 我想创建一个可以容纳10个元素的空列表(或最好的方法)。 之后,我想在该列表中分配值,例如,应该显示0到9: 但是,当我运行此代码时,它会产生错误,或者在其他情况下,它只会显示(空)。 有人可以解释为什么吗? 问题答案: 你不能分配给类似的列表,除非该列表已至少已使用元素初始化。你需要使用append将元素添加到列表的末尾。。 (如果使用字典,则可以使用分配符号)。 创建一个空列表:
问题内容: 在应使用相同的列表时,我看到一些不一致之处。(Python 2.7.5) 有人有一个简单的解释吗? 问题答案: 使用列表文字,VM会创建具有设置长度的列表。当将序列传递给构造函数时,元素将被一个接一个地添加(通过),因此在适当时调整了列表的大小。由于调整大小操作是为了分摊成本而进行的,因此最终列表通常会比源列表大。
相关主题: 卡达内算法
问题内容: 与列表变平相反。 给定一个列表和一个长度为n的列表,返回一个长度为n的子列表的列表。 一个例子: 如果列表是: n是: 返回: 有没有一种更雄辩/简洁的方法? 顺便说一句,将列表追加到列表时(在上面的上下文中)是首选: 要么: 鉴于(根据Summerfeild的“ Python 3编程”),它们是一样的吗? 谢谢。 问题答案: 这样的列表列表可以使用列表理解来构造: 还有石斑鱼成语: