【问题标题】:Difference between checking hash map and iterating through keys in hash map检查哈希映射和遍历哈希映射中的键之间的区别
【发布时间】:2014-02-27 09:10:30
【问题描述】:

我有一个单词列表,每个单词都有相应的分数。我正在梳理和匹配 .txt 文件中一大块文本中的每个单词与单词列表中的单词。 .txt 文件最多可包含 10,000 行文本。

当我第一次这样做时,我使用了一种非常暴力和幼稚的方法来匹配我的单词列表中的单词和我的 .txt 文件。虽然我使用了hash map,但是我没有正确使用hash map,还不如把它当成一个list来用了。所以代码是这样写的:

for(int i=0; i<words.length; i++){
    for(int j=0; j<wordListType.size(); j++){
        Map<String, Integer> hmap = wordListType.get(j).getMap();
        for(Map.Entry<String, Integer> entry : hmap.entrySet()){
            if(words[i].contains(entry.getKey())){
                foo();
            }
        }
    }
}

words 是一个 String[] ,其中包含文本文件中的单个单词。 wordListType 是一个类的 ArrayList,其中包含我正在搜索的关键字的哈希映射。它是一个 ArrayList,因为有多种类型的单词列表。 getMap() 是我自己在 WordList 类中的辅助方法。

之后,我发现我的代码效率低下,而且我没有充分利用我的哈希映射。于是我把代码改成如下:

for(int i=0; i<words.length; i++){
    for(int j=0; j<wordListType.size(); j++){
        Map<String, Integer> hmap = wordListType.get(j).getMap();
        Integer val = null;
        if((val = hmap.get(words[i])) != null){
            foo();
        }
    }
}

这样我不会像第一种方法那样遍历 hmap 中的每个键,而是使用 O(1) HashMap.get() 方法。

但是,第二种有效的方法并没有产生我想要的结果。

我不太清楚为什么这些词的匹配方式不同。据我所见,它们都应该提供完全相同的答案,除了我后面的代码应该做得更快。相反,第一种迭代哈希映射的所有键的方法实际上是产生我想要的结果(我手动检查了这个),而第二种方法没有。

我已经测试过的哈希图中没有空值。我已经查看了哈希映射的实现,所以我不太明白为什么这不起作用。我在这里遗漏了什么,还是有其他不相关的东西影响了我的结果?非常感谢任何帮助。

【问题讨论】:

  • 你在哪里设置索引变量k(在hmap.get(words[k])?不应该是i吗?是错字吗?
  • 是的,我的实际代码略有不同,所以我在提供示例时忘记更改它。谢谢你指出这一点。编辑了我原来的帖子。

标签: java hash hashmap


【解决方案1】:

您使用的两个 if 条件不会测试同一件事。让我们举个例子,words[i] 已“测试”并且您的地图包含键“测试”:

if(words[i].contains(entry.getKey())) {

此条件检查您的 Word[i] 是否包含您的映射键,这意味着将评估 if 块。

if((val = hmap.get(words[k])) != null){

此条件检查您的地图是否包含字符串 word[k](“tested”),因为它仅包含“test”,因此评估结果为 false。

我相信对于您的用例,第二个实现会给出您正在寻找的结果。

【讨论】:

  • 啊当然。绝对是这样。愚蠢的监督。非常感谢。
  • 如果解决了你的问题,你能接受吗?谢谢:)
【解决方案2】:

如果我理解正确,words[i] 就是String。在第一个解决方案中,您将匹配具有映射键作为子字符串的每个单词。第二种情况你做完全匹配。

这个:

words[i].contains(entry.getKey())

将匹配每个具有entry.getKey() ssubstring 的单词。即它将匹配alabala 的字符串ala

这里:

(val = hmap.get(words[k])) != null

哪个写得更好:

hmap.contains(words[k])

您检查地图是否包含与给定单词完全匹配的键。在这种情况下,ala 将不匹配单词 alabala

【讨论】:

  • 谢谢。有没有办法做这种类型的代码 (val = hmap.get(words[k])) != null with contains 吗?我是否必须先对子字符串进行包含,然后获取该键的值?希望有更快的方法
  • 让我改写我的问题,因为这令人困惑。我意识到我基本上是在查看 hmap 是否包含单词的子字符串作为其键之一。除了像我在第一种方法中那样遍历 hmap 中的所有键之外,还有其他简单的方法吗?
  • @Nopiforyou 我喜欢这个问题——因为我喜欢算法问题。但是,我认为这是完全独立的事情,值得一等的 SO 问题。问它..与此同时,我将尝试找出解决它的最佳算法。
猜你喜欢
  • 2019-02-26
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 2011-06-02
相关资源
最近更新 更多