繁体   English   中英

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

[英]How To Count Word Occurence in a String 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("\n\t\r(){},:;!?.[]");

        //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表示不是单词字符的任何内容(即,不是字母的任何内容)。

如果您希望分割任何标点符号或空格,则在正则表达式中\\W后面应有一个+ 这会将所有后续的都计入同一定界符。 这就是为什么您当前在答案中得到{=2的原因(输入中有两个“。”实例,它们被拆分解释为定界符,空值,定界符)。

似乎您希望将“ 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());

我将以短跑选手的回答为基础,因为他完全忽略了问题中可以更改和无法更改的内容。

尽可能多地使用Java 8。 因为地图已经初始化,所以这对您来说真的行不通,所以奇怪的是您创建了另一个地图并替换了它

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功能并使用原始创建的地图。

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. 对于拆分数组中的每个字符串: 检查您是否具有等于字符串的键:是:获取值,增加计数并将值放回去。 否:插入值= 1的新密钥

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM