[英]More efficient alternative to these “for” loops?
我正在学习Java入门课程,而我的最新项目之一是确保数组不包含任何重复的元素(具有不同的元素)。 我使用了一个for循环和一个内部for循环,并且它起作用了,但是我听说您应该避免在程序中使用许多迭代(并且我类中的其他方法也有很多迭代)。 有什么有效的替代方法吗? 我当然不要求代码,只是“概念”。 可能会有递归的方式做到这一点吗? 谢谢!
数组大小通常<= 10。
/** Iterates through a String array ARRAY to see if each element in ARRAY is
* distinct. Returns false if ARRAY contains duplicates. */
boolean distinctElements(String[] array) { //Efficient?
for (int i = 0; i < array.length; i += 1) {
for (int j = i + 1; j < array.length; j += 1) {
if (array[i] == array[j]) {
return false;
}
}
} return true;
}
首先, array[i] == array[j]
测试引用是否相等。 这不是测试String
是否相等的方法。 我将每个元素添加到Set
。 如果没有成功添加任何元素(因为它是重复元素),则Set.add(E)
返回false
。 就像是,
static boolean distinctElements(String[] array) {
Set<String> set = new HashSet<>();
for (String str : array) {
if (!set.add(str)) {
return false;
}
}
return true;
}
您可以在没有短路的情况下渲染以上内容
static boolean distinctElements(String[] array) {
Set<String> set = new HashSet<>(Arrays.asList(array));
return set.size() == array.length;
}
“效率”几乎总是一个权衡。 有时,有些算法会比其他算法好一些,但通常只有在某些情况下才更好。
例如,上面的代码:时间复杂度为O(n^2)
。
一种改进可能是对字符串进行排序:然后,您可以通过比较元素是否等于其邻居来比较字符串。 由于排序,这里的时间复杂度降低为O(n log n)
,它支配了元素的线性比较。
但是-如果您不想更改数组的元素-例如,您的代码的其他部分依赖于它们的原始顺序-现在,您还必须复制数组,然后对其进行排序,然后寻找重复项。 这不会增加总时间或存储复杂性,但是会增加总时间和存储 ,因为需要完成更多的工作并且需要更多的内存。
大数表示法只会使您无视乘法因素 ,从而束缚了时间。 也许您只能访问一个非常慢的排序算法:实际上,事实证明,仅使用O(n^2)
循环会更快,因为那样您就不必调用非常慢的排序了。
当您的输入非常小时,可能会出现这种情况。 经常引用的算法是时间排序较差,但实际上在实践中有用的算法是冒泡排序:在最坏的情况下,它是O(n^2)
,但是如果数组很小和/或接近排序,它就可以实际上可以非常快速地实现,并且非常容易实现-永远不要忘记编写和调试代码的效率低下,以及当SO无法正常工作时不得不在SO上提问。
如果您知道元素已经排序,该怎么办,因为您对它们的来源有所了解。 现在,您可以简单地遍历数组,比较邻居,时间复杂度现在为O(n)
。 我不记得我在哪里读的书,但是我曾经看到一篇博客文章说(我释义):
一台给定的计算机永远无法更快运行。 它只能做更少的工作。
如果您可以利用某些财产来减少工作量,那将提高效率。
因此,效率是一个主观标准:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.