【问题标题】:Finding Duplicate Algorithm - Java查找重复算法 - Java
【发布时间】:2011-07-31 03:23:07
【问题描述】:

我有一组值,一个数组列表,我必须找到重复的键。一种方法是使用 2 个循环。并遍历列表中每个返回 O(n2) 的值。

另一件事,我可以做的是将值作为键放在 HashTable 中。我相信,如果哈希表中已经有相同的键,它会抛出异常。但它不会抛出异常

    Hashtable<String, String> ht = new Hashtable<String, String>();

    for (int i = 0; i<20; i++){
        ht.put(String.valueOf(i%10), String.valueOf(i%10));
    }

我理解错了吗?如果其中已经有相同的键,hastable/hashmap 不会抛出异常吗?

【问题讨论】:

  • Java 文档是怎么说的?
  • Hashtable 是一个遗留类,在 Java 1.2 (1998) 中被替换,我建议你不要使用它,除非你必须这样做。
  • 执行看跌期权的一种略短的方法是ht.put(""+i%10, ""+i%10); ;)

标签: java algorithm hashtable hashmap


【解决方案1】:

我的建议是你想要 HashSet 而不是 Hashtable

Set<String> ht = new HashSet<String>();

for (int i = 0; i<20; i++){
    if ( !ht.add(String.valueOf(i%10)) ) {
       //it already existed, throw an exception or whatever
    }
}

如果您不关心添加到地图中的,您几乎肯定需要Set 而不是Map/table。

【讨论】:

  • +1:解决这个问题的正确 ADT 是 set,而不是 table
【解决方案2】:

不,它不会抛出异常,它只是替换旧值。你可以通过调用get来检查一个值是否已经存在:

if (ht.get(key) != null) {
  // value already exists
}

编辑:正如@Mark Peters 所建议的,containsKey 是一个更简单,有时甚至更好的解决方案。

【讨论】:

  • ht.containsKey(key) 怎么样?仅当您从未映射到值 null 时,上述内容才适用。
  • 我可以按照你写的方式解决。但是是否有任何其他集合或引发异常的东西?
  • @Mark Peters:很好,containsKey 确实是一个更好的解决方案。
  • @alee:你为什么想要例外?
  • 我正在开发的应用程序已经有了一个不错的异常处理框架。通过它处理错误会更容易并且与原始代码兼容,而不是添加 if/else 块。
【解决方案3】:

您可以在API docs 中看到put 返回null,如果该键之前的表中没有任何内容,则返回该键的先前值(如果有)。 (这两种情况都不会抛出异常。)

【讨论】:

    【解决方案4】:

    您可能想阅读performance characteristics of hashes

    例如,哈希将回答“此密钥是否存在?”的问题。快速,这可能对您的算法有所帮助。

    【讨论】:

      【解决方案5】:

      根据 Java Docs,如果 key 或 value 为 null,put 可能引发的唯一异常是 NullPointerException。您可以将循环更改为:

      for(int i = 0 ; i < 20 ; i++) {
          if (ht.containsKey(String.valueOf(i%10)))
              throw new Something();
      
          ht.put(String.valueOf(i%20), True);
      }
      

      【讨论】:

        【解决方案6】:

        来自 JavaDoc:

        放 公共对象放置(对象键, 对象值) 将指定键映射到此哈希表中的指定值。键和值都不能为空。 可以通过使用与原始键相同的键调用 get 方法来检索该值。 指定者: 放入接口地图 指定者: 放入类词典 参数: key - 哈希表键。 价值——价值。 回报: 此哈希表中指定键的前一个值,如果没有,则返回 null。 抛出: NullPointerException - 如果键或值为 null。 也可以看看: Object.equals(Object), get(Object)

        看起来它会让您覆盖该值,但随后它会将旧值作为返回对象提供给您。

        【讨论】:

          【解决方案7】:

          这是最简单的方法:

          List yourList;
          HashSet noDuplicates = new HashSet(yourList);
          HashSet duplicates = new HashSet(yourList).removeAll(noDuplicates);
          

          【讨论】:

            【解决方案8】:

            根据您的内存与运行时限制,如果您的空间有限,我会推荐一些东西:

            您可以对数组进行排序(如果您使用快速排序之类的东西,最坏的情况是 O(nlog_n)),然后遍历它以查找相邻元素中的重复项。

            希望对你有帮助

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-29
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-05-15
              • 1970-01-01
              相关资源
              最近更新 更多