如何计算字符串HashMap中的单词出现次数



我想知道如何修复我的代码,使我的输出是正确的。我只能编辑代码的特定部分。非常感谢

这是我的代码

import java.util.HashMap;
public class OccurenceChecker {
    public static void main(String[] args) 
    { 
        //CANT BE FIXED
        String phrase = "Good Morning. Welcome to my store. My store is a grocery store.";
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        String[] ignored = phrase.split("ntr(){},:;!?.[]");
        //CAN BE FIX THIS POINT ON.
        for (String ignore : ignored) 
        {
            Integer count = map.get(ignore);
            if (count == null) 
            {
                count = 0;
            }
            map.put(ignore, count + 1);
        }
        for (int i = 0; i< ignored.length; i++)
        {
            System.out.println(ignored[i]);
        }
        System.out.println(map);
    }
}
预期输出

{a=1, Morning=1, grocery=1, Welcome=1, is=1, to=1, store=3, Good=1, my=2}

我的输出

{=2, a=1, Morning=1, grocery=1, Welcome=1, is=1, to=1, store=3, Good=1, my=1, My=1}

您可以考虑以下几点建议:

在正则表达式中,W指的是任何不是单词字符的东西(即任何不是字母的东西)。

如果你想分割任何标点或空格,那么你应该在你的regexp中W之后有一个+。这将把所有后续的分隔符算作同一分隔符的一部分。这就是为什么你目前在你的答案中得到{=2(有两个例子)。"在你的输入中,被分割解释为分隔符(null, delimiter)。

看起来好像您希望'my'和'my'被认为是同一个字符串。在这种情况下,您应该在将它们添加到映射之前使用toLowerCase

如果你正在使用Java 8,一个很好的简单的方法来维护一个运行的增量映射

Map<String,Integer> wordCount = new HashMap<>();
wordCount.put(word, wordCount.getOrDefault(word, 0) + 1);

同样,在Java 8中,您可以一次完成所有这些

Map<String,Long> wordCount = Arrays.stream(phrase.toLowerCase().split("\W+"))
    .collect(Collectors.groupingBy(Function.identy(), Collectors.counting());

我将以sprinter的回答为基础,因为他完全忽略了问题中可以和不能改变的部分。

尽量使用Java 8。这在你的情况下不会起作用,因为map已经初始化了,所以你创建另一个并替换它是很奇怪的

map = Arrays.stream(ignored)
        .filter(s -> !s.isEmpty()) // removed empty strings
        .map(String::toLowerCase) // makes all the strings lower case
        .collect(Collectors.groupingBy(Function.identy(), Collectors.counting());

使用更基本的Java 8特性并使用最初创建的map。

Arrays.stream(ignored)
        .filter(s -> !s.isEmpty()) // removed empty strings
        .map(String::toLowerCase) // makes all the strings lower case
        .forEach(s -> map.put(s, map.getOrDefault(s, 0) + 1)

Java 8

for (final String s : ignored) {
    if (s.isEmpty()) {
        continue; // skip empty strings
    }
    final String lowerS = s.toLowerCase();
    if (map.containsKey(lowerS)) {
        map.put(lowerS, map.get(lowerS) + 1)
    } else {
        map.put(lowerS, 1)
    }
}

您的方法并不完全正确(如果您在那里有其他符号呢?)这样做:

  1. 用空格替换所有非字母数字字符。
  2. 基于分割空间(\s+)。
  3. 对于分割数组中的每个字符串:a.检查是否有一个键等于字符串:YES:获取值,增加计数和把值放回去。No:插入value =1的新密钥

最新更新