我找到了两种从字符串数组中找到重复值的方法。
第一种方式:
private static String FindDupValue(String[] sValueTemp) {
for (int i = 0; i < sValueTemp.length; i++) {
String sValueToCheck = sValueTemp[i];
if(sValueToCheck==null || sValueToCheck.equals(""))continue;
for (int j = 0; j < sValueTemp.length; j++) {
if(i==j)continue;
String sValueToCompare = sValueTemp[j];
if (sValueToCheck.equals(sValueToCompare)){
return sValueToCompare;
}
}
}
return "";
}
第二种方式:
private static String FindDupValueUsingSet(String[] sValueTemp) {
Set<String> sValueSet = new HashSet<String>();
for(String tempValueSet : sValueTemp) {
if (sValueSet.contains(tempValueSet))
return tempValueSet;
else
if(!tempValueSet.equals(""))
sValueSet.add(tempValueSet);
}
return "";
}
两种方法都是正确的。
我的问题是哪种方法最好?为什么?或者有没有其他最好的方法来找出数组的重复值?
答案 0 :(得分:2)
Set的好处在于它的add operation会返回
true
如果此集合尚未包含指定的元素。
public static void main(String[] args) {
Set<String> set = new HashSet<>();
String[] stringsToTest = {"a", "b", "c", "a"};
for (String s : stringsToTest) {
boolean notInSetYet = set.add(s);
if (!notInSetYet) {
System.out.println("Duplicate: " + s);
}
}
}
输出:
重复:a
答案 1 :(得分:1)
第二种方式。
使用Set对此操作更有效,因为sValueSet.contains(tempValueSet)
使用支持映射(因此使用哈希码和快速查找时间)而不是完全迭代。
答案 2 :(得分:1)
这两种方法在算法复杂性方面几乎相似。
第一种方法的复杂性是O(N * N)
,其中N
是数组的长度。我不认为有必要解释原因,但以防万一 - 嵌套循环需要N * N
个时间单位,这会带来复杂性。
至于第二种方法 - 拥有HashSet
允许您使用常量复杂度(O(1)
)进行搜索,因为搜索基于String
的哈希值。可以认为这种方法更有效,但实际上并不是那么多,因为我们需要在HashSet
上遇到 insert 操作。
添加到HashSet
具有复杂性O(N)
(最糟糕的情况)。对于N
String对象,您可能会进行N
插入操作,这再次提供O(N * N)
的复杂性。
因此,总而言之,这两种方法都有相似的费用。不过,我更喜欢第二种,因为它更具可读性。
答案 3 :(得分:1)
在第二个循环的第一个方法中,我相信如果你将循环起始点从j = 0改为j = i,它会使它更快。因为你会避免两次比较两个值
private static String FindDupValue(String[] sValueTemp) {
for (int i = 0; i < sValueTemp.length; i++) {
String sValueToCheck = sValueTemp[i];
if(sValueToCheck==null || sValueToCheck.equals(""))continue;
for (int j = i; j < sValueTemp.length; j++) {
if(i==j)continue;
String sValueToCompare = sValueTemp[j];
if (sValueToCheck.equals(sValueToCompare)){
return sValueToCompare;
}
}
}
return "";
}
答案 4 :(得分:1)
这似乎是运行在O(n)中的最快方法之一,假设HashSet.add
的摊销O(1),并且通过省略{{1}的使用,每次迭代只需要一次哈希计算}}。
确实,String缓存了hashcode(感谢Jonah),这段代码概括了省略的概念
contains
。
contains