我在从ArrayList中删除重复项时遇到问题。这是为了大学的任务。这是我已有的代码:
public int numberOfDiffWords() {
ArrayList<String> list = new ArrayList<>();
for(int i=0; i<words.size()-1; i++) {
for(int j=i+1; j<words.size(); j++) {
if(words.get(i).equals(words.get(j))) {
// do nothing
}
else {
list.add(words.get(i));
}
}
}
return list.size();
}
问题出在numberOfDiffWords()
方法中。填充列表方法工作正常,因为我的讲师给了我一个样本字符串(包含4465个单词)进行分析 - 打印words.size()
给出了正确的结果。
我想返回新ArrayList的大小并删除所有重复项。
words
是一个ArrayList类属性。
更新:我应该提到我只允许在分配的这一部分使用基于动态索引的存储,这意味着没有基于散列的存储。
答案 0 :(得分:5)
由于这是一项任务,我不打算编写代码。但是,我建议采用不同的方法。
subList()
方法从一开始就构建一个数组视图,但不包括当前元素contains()
来测试当前元素是否在上一步构建的子列表中我推荐的方法应该会产生更简单易懂的代码。请注意,所有这些都是O(n 2 )解决方案(正如您的解决方案一样)。
如果赋值允许修改数组,则另一种方法是对数组进行排序。然后相等的元素将相邻,并且很容易计算有多少是唯一的。这是一种O(n log(n))方法。 (你也可以制作一个数组的副本,这不会改变渐近的复杂性,但会减慢解决方案。)
如果不使用某种散列函数(HashSet
或HashMap
),您将无法获得更好的效果。
答案 1 :(得分:2)
如果您打算使用该方法,那么这就是您的问题:修改if-then-else,使其不会在第二个循环中添加单词。在内部循环中验证是否存在重复项,使用布尔变量,如果没有重复,则在第二个循环后将该单词添加到列表中。
答案 2 :(得分:0)
不要在整个长度上运行循环,而是应该通过在arraylist上调用 contains()方法来检查重复。
word.subList(fromIndex, toIndex).contains(arg);
这样你的代码就会非常简洁。
答案 3 :(得分:0)
如果使用嵌套for循环结构进行迭代,删除每个元素的dupes,然后将其余元素添加到新数组,则可以返回较小的数组。我不确定这是否是最快的方法,但它确实有效。
// Delete all dupes
for ( i=0; i<words.length; i++ ) {
String word = words[i];
for ( j=(i+1); j<words.length; j++) {
if (words[j] == words[i]) {
words[j] = null;
}
}
}
// Count the array w/o nulls
int countEl = 0;
for (i=0; i<words.length; i++) {
if (words[i] != null) {
countEl++;
}
}
// Make a new array
String[] newArray = new String[countEl];
for (i=0; i<words.length; i++) {
if (words[i] != null) {
countEl.push(words[i]);
}
}
答案 4 :(得分:0)
如果您想让它更简单,请试试这个
final ArrayList duplicateWords = new ArrayList() ;
ArrayList<String> words = new ArrayList() {
@Override
public boolean add(Object e) {
if( !contains(e) ) {
return super.add(e);
} else {
duplicateWords.add(e);
return false ;
}
}
};
System.out.println("Unique words : " + words.size());
System.out.println("Duplicate words : " + duplicateWords.size());
这是另一个答案。