我有这段代码,我无法理解代码是如何工作的,它如何删除与indexOf和lastIndexOf重复的代码?
ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");
System.out.println("Duplicates List "+lst);
Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
System.out.println("Distinct List "+lst);
答案 0 :(得分:2)
这是一种非常笨重(即低效)的方式 1 。
它是如何运作的?
这个谓词:
lst.indexOf(s) != lst.lastIndexOf(s)
正在测试列表中是否有两个(或更多)s
个实例。逻辑是,如果列表中第一个s
和最后一个s
的位置不同,那么必须至少其中两个。然后我们删除最后一个实例。
由于我们对原始列表中的每个字符串执行此操作,如果列表中有给定字符串的M个实例,则该测试将对该字符串执行M次,并且将成功M - 1次,因此删除M - 其中一个例子。最后,您只剩下每个不同字符串的一个实例;即没有重复。
1 - O(N^2)
,可以消除O(N)
O(N)
临时空间中的重复项。一般方法如下:
HashSet
。s
:
s
不在集合中:
答案 1 :(得分:1)
尝试在那里再多放一些印刷语句,我想你能亲自看看!
for (Object s : st) {
System.out.println(s);
System.out.println(lst.indexOf(s));
System.out.println(lst.lastIndexOf(s));
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
答案 2 :(得分:1)
如何删除带有indexOf和lastIndexOf的重复项?
if (lst.indexOf(s) != lst.lastIndexOf(s))
上面的代码获取列表中第一次出现s
的索引(如果它存在-1
),并且还获取最后一次出现s
的索引(如果如果两个索引都是相同,那么没有重复,如果它们不是>,那么它在列表中是否存在-1
) em> 相同然后我们找到了副本,因此它会从列表中删除。
根据您当前正在处理的代码,我们可以确认字符串"ABC"
在集合中出现两次,一个在索引0
,另一个在索引1
因此,当if
语句检查到这一点时,我们可以保证控件将进入if
语句,因为它们不相同的索引(意味着有< em>至少两次出现字符串s
),同样字符串"ABCD"
在索引1
和2
的列表中出现两次(请注意这一点)最后一次出现"ABC"
的时间已从列表中删除,因此"ABCD"
占用了索引1
的插槽,因为列表的性质会调整自身大小)意味着控制将再次进入if
阻止因为他们不相同的索引。
最终,s
的最后一次出现将从列表中删除,并且每次迭代循环都会重复相同的过程。
您可以通过remove duplicates from a list更有效的方式进行调查,因为它可以缩短性能时间。