从字符串数组中查找重复值

时间:2015-12-25 12:22:27

标签: java arrays

我找到了两种从字符串数组中找到重复值的方法。

第一种方式:

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 "";
  }

两种方法都是正确的。

我的问题是哪种方法最好?为什么?或者有没有其他最好的方法来找出数组的重复值?

5 个答案:

答案 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