在Java中实现一种方法来计算L1和L2之间的差异()。L1 \ L2 = {x | x∈L1和x∉L2}。
到目前为止,这是我的实现:
public static <AnyType extends Comparable<? super AnyType>>
void difference(List<AnyType> L1, List<AnyType> L2, List<AnyType> Difference){
if(L1 == null){
Difference = null;
}
else if(L2 == null){
Difference = L1;
}
else if(L1.size()==0 || L2.size()==0){
Difference = L1;
}
else{
Iterator<AnyType> it1 =L1.listIterator();
Iterator<AnyType> it2 =L2.listIterator();
AnyType a = it1.next();
AnyType b = it2.next();
while(true){
if(a.compareTo(b)>0){
if(it2.hasNext()){
b = it2.next();
}
else{
Difference.add(a);
while(it1.hasNext()){
a = it1.next();
Difference.add(a);
}
break;
}
}
else if(a.compareTo(b)<0){
Difference.add(a);
if(it1.hasNext()){
a = it1.next();
}
else break;
}
else {
if(it1.hasNext()){
a =it1.next();
}
else break;
}
}
}
System.out.println("Difference Set: " + Arrays.toString(Difference.toArray()));
}
这不是简单的解决方案,而是实现两个嵌套的for循环并将正确的元素保存到结果列表中,该解决方案是O(n ^ 2)。
另一种可能的解决方案是使用二进制搜索来搜索第二个列表,该算法将为O(n * Log(n))
此处实现的解决方案,尝试仅浏览一次列表并在第一遍中完成,这将是O (n)线性。
该算法运行良好,但是感觉它仍然可以使用一些优化,感觉就像意大利面条代码大声笑。有什么指针可以帮助我优化这一点吗?
我看到的第一件事是您a.compareTo(b)
对循环中的每个迭代执行两次。而是使用compareTo
一次并将结果存储在两个if
语句中。
其次,使用一致的命名方案,例如objA
和,iterA
而不是a
和it1
。这只会使其更容易理解。就此而言,不要害怕更长的名称。listA
比起l1
可能会有几个额外的字符,但值得一读。(此外,请不要忘记您不应该以大写字母开头的变量,这L1
是双重不妙的。)
最后,发表评论评论评论。我知道这种算法,因此我可以很好地遵循代码,但是它远不能自我记录。对每个if语句进行注释并循环,以记录条件是什么,为什么要检查以及如何对结果进行处理。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句