【问题标题】:Find duplicate value from string array [duplicate]从字符串数组中查找重复值[重复]
【发布时间】:2015-12-25 12:22:27
【问题描述】:

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

第一种方式:

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

这两种方法都是正确的。

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

【问题讨论】:

    标签: java arrays


    【解决方案1】:

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

    输出:

    重复:一个

    【讨论】:

      【解决方案2】:

      第二种方式。

      对于此操作,使用 Set 效率更高,因为 sValueSet.contains(tempValueSet) 使用支持映射(因此使用哈希码和快速查找时间)而不是完全迭代。

      【讨论】:

        【解决方案3】:

        这两种方法在算法复杂度方面几乎相似。

        第一种方法的复杂度是O(N * N),其中N 是数组的长度。我认为没有必要解释原因,但以防万一 - 嵌套循环需要 N * N 时间单位,这会带来复杂性。

        至于第二种方法 - 使用 HashSet 可以让您以恒定的复杂性进行搜索 (O(1)),因为搜索是基于 String 的哈希值。可以认为这种方法更有效,但实际上并没有那么多,因为我们需要遇到HashSet上的insert操作。

        添加到HashSet 是复杂的O(N)(最坏的情况)。对于N String 对象,您可能有N 插入操作,这又会增加O(N * N) 的复杂性。

        因此,总而言之,这两种方法的费用相似。不过,我更喜欢第二个,因为它更具可读性。

        【讨论】:

        • HashSet 插入复杂度即使在最坏的情况下仍然摊销O(1),而不是O(n)
        • 如果知道集合的大小则为O(1),否则为O(n)
        • 不,即使你不知道大小,它也是摊销 O(1)。当您不知道大小并且它达到最坏的情况(当前项目数 >= 可用大小)时,该集合将根据负载因子(和初始容量)增长一次。 O(n) 那里什么也没有。 Java 文档保证了这一点。
        • @LeleDumbo 如果散列散布 used 键(而不是潜在键),则每个项目的 O(1)。最坏的情况是如果所有哈希码都发生冲突:通过作为链表的 java7 和 O(N),但 java8 切换到树并且似乎是 O(log N)。有基于此的拒绝服务攻击,您可以在其中发送例如Tomcat 或 IIS 的 HTTP 请求包含数千个选择发生冲突的 URL 参数,并且需要数小时的 CPU 来处理,而不是十分之一秒。
        【解决方案4】:

        在第二个循环的第一种方法中,我相信如果您将循环起点从 j=0 更改为 j=i,它会使其更快。因为您将避免两次比较 2 个值

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

        }

        【讨论】:

          【解决方案5】:

          这似乎是最快的方法之一,在 O(n) 中运行,假设 HashSet.add 的摊销 O(1),加上通过省略 contains 的使用,每次迭代只需要一次哈希计算。 确实String缓存了hashcode(感谢Jonah),这段代码概括了省略的概念 contains.

          private static String FindDupValueUsingSet(String[] sValueTemp) {
              Set<String> sValueSet = new HashSet<String>();
              for(String tempValueSet : sValueTemp)
                  if (!tempValueSet.equals("")) //exclude empty Strings (add null checking if required)
                      if (!sValueSet.add(tempValueSet))
                          return tempValueSet;
              return "";
          }
          

          【讨论】:

          • “加上每次迭代只需要一次哈希计算” String 的 hashCode (一个不可变的)被缓存,所以无论你使用多少次都不会重新计算。 stackoverflow.com/questions/21000611/…
          • 是的,字符串确实如此
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-21
          • 2016-07-08
          • 1970-01-01
          • 2018-06-01
          • 2021-12-03
          • 1970-01-01
          相关资源
          最近更新 更多