创建 HashMap,其中键等于文本中最常见的第一个字母,值是从该字母开始的所有单词的链表

Posted

技术标签:

【中文标题】创建 HashMap,其中键等于文本中最常见的第一个字母,值是从该字母开始的所有单词的链表【英文标题】:Create HashMap where key equals most frequent first letter in a text, and value is a linked list of all words starting on that letter 【发布时间】:2022-01-19 14:25:11 【问题描述】:

我承认这是一个家庭作业。但这对我来说很难,我需要一些建议。方法getWordsInLyrics() 将文本拆分为单词。现在如何获得最常见的第一个字母,以及从那个字母开始的单词?将其存储在HashMap<String letter, LinkedList<String words >> wordBegins = new HashMap<>(); 我必须使用charAt(0) 吗?

import java.util.HashMap;
import java.util.LinkedList;

public class LyricsCounter 

    private static final String LYRICS = "Dwunastu braci, wierzac w sny, zbadalo mur od marzen strony,\n" +
            "A poza murem plakal glos, dziewczecy glos zaprzepaszczony.\n" +
            "I pokochali glosu dzwiek i chetny domysl o Dziewczynie,\n" +
            "I zgadywali ksztalty ust po tym, jak spiew od zalu ginie...\n" +
            "Mowili o niej: \"lka, wiec jest!\" - I nic innego nie mowili,\n" +
            "I przezegnali caly swiat - i swiat zadumal sie w tej chwili...\n" +
            "Porwali mloty w twarda dlon i jeli w mury tluc z loskotem!\n" +
            "I nie wiedziala slepa noc, kto jest czlowiekiem, a kto mlotem?\n" +
            "\"O, predzej skruszmy zimny glaz, nim smierc Dziewczyne rdza powlecze!\" -\n" +
            "Tak, walac w mur, dwunasty brat do jedenastu innych rzecze.\n" +
            "Ale daremny byl ich trud, daremny ramion sprzeg i usil!\n" +
            "Oddali ciala swe na strwon owemu snowi, co ich kusil!\n" +
            "lamia sie piersi, trzeszczy kosc, prochnieja dlonie, twarze bledna...\n" +
            "I wszyscy w jednym zmarli dniu i noc wieczysta mieli jedna!\n" +
            "Lecz cienie zmarlych - Boze moj! - nie wypuscily mlotow z dloni!\n" +
            "I tylko inny plynie czas - i tylko mlot inaczej dzwoni...\n" +
            "I dzwoni w przod! I dzwoni wspak! I wzwyz za kazdym grzmi nawrotem!\n" +
            "I nie wiedziala slepa noc, kto tu jest cieniem, a kto mlotem?\n" +
            "\"O, predzej skruszmy zimny glaz, nim smierc Dziewczyne rdza powlecze!\" -\n" +
            "Tak, walac w mur, dwunasty cien do jedenastu innych rzecze.\n" +
            "Lecz cieniom zbraklo nagle sil, a cien sie mrokom nie opiera!\n" +
            "I powymarly jeszcze raz, bo nigdy dosc sie nie umiera...\n" +
            "I nigdy dosc, i nigdy tak, jak pragnie tego ow, co kona!...\n" +
            "I znikla tresc - i zginal slad - i powiesc o nich juz skonczona!\n" +
            "Lecz dzielne mloty - Boze moj - mdlej nie poddaly sie zalobie!\n" +
            "I same przez sie bily w mur, huczaly spizem same w sobie!\n" +
            "Huczaly w mrok, huczaly w blask i ociekaly ludzkim potem!\n" +
            "I nie wiedziala slepa noc, czym bywa mlot, gdy nie jest mlotem?\n" +
            "\"O, predzej skruszmy zimny glaz, nim smierc Dziewczyne rdza powlecze!\" -\n" +
            "Tak, walac w mur, dwunasty mlot do jedenastu innych rzecze.\n" +
            "I runal mur, tysiacem ech wstrzasajac wzgorza i doliny!\n" +
            "Lecz poza murem - nic i nic! Ni zywej duszy, ni Dziewczyny!\n" +
            "Niczyich oczu ani ust! I niczyjego w kwiatach losu!\n" +
            "Bo to byl glos i tylko - glos, i nic nie bylo oprocz glosu!\n" +
            "Nic - tylko placz i zal i mrok i niewiadomosc i zatrata!\n" +
            "Takiz to swiat! Niedobry swiat! Czemuz innego nie ma swiata?\n" +
            "Wobec klamliwych jawnie snow, wobec zmarnialych w nicosc cudow,\n" +
            "Potezne mloty legly w rzad, na znak spelnionych godnie trudow.\n" +
            "I byla zgroza naglych cisz. I byla proznia w calym niebie!\n" +
            "A ty z tej prozni czemu drwisz, kiedy ta proznia nie drwi z ciebie?";

    private static String[] getWordsInLyrics() 
        return LYRICS.split("\\W+");
    

    public static void main(String[] args) 
        HashMap<String, LinkedList<String>> wordBegins = new HashMap<>();
    

【问题讨论】:

是的,使用for 循环。对于数组中的每个单词,获取第一个字母 - 可能转换为小写。然后检查你的地图,看看那封信是否在那里。如果没有,请创建一个LinkedList 并将其添加到哈希映射中,键为字母。最后,将单词添加到列表中。 请注意,charAt 返回 char,但您的地图使用 String。您要么需要将char 转换为String,要么使用word.substring(0, 1) 必须使用 Map 来存储 SINGLE key -> value 对(即使 value 是链表),这有点奇怪。相反,如果我们将所有具有相同起始字符的单词分组到 key 下,这将是像 a -&gt; [a, ab, ac, ..]; b-&gt;[ba, bab, ...] 这样的字符,我们可以通过比较每个列表中的单词数量轻松判断哪个字符在开始时最常使用(这就是我的猜测你的作业是关于)。 String firstLetter = arr[i].substring(0,1); if (!wordBegins.containsKey(firstLetter)) wordBegins.put(firstLetter, new LinkedList&lt;String&gt;()); wordBegins.get(firstLetter).add(arr[i]); 【参考方案1】:

在填充地图时可以轻松跟踪最常见的字符及其频率,然后在循环后检索适当的单词列表:

Map<Character, LinkedList<String>> map = new HashMap<>();
char maxChar = ' ';
int maxFreq = 0;
for (String word : LYRICS.split("\\W+")) 
    char letter = Character.toLowerCase(word.charAt(0));
    map.computeIfAbsent(letter, k -> new LinkedList<>()).add(word);
    int freq = map.get(letter).size();
    if (maxFreq < freq) 
        maxFreq = freq;
        maxChar = letter;
    

System.out.println("Most frequent: " + maxChar + "; frequency = " + maxFreq);
System.out.println(map.get(maxChar));

输出:

Most frequent: i; frequency = 47
[I, i, I, I, innego, I, i, i, I, innych, ich, i, ich, I, i, I, inny, i, inaczej, I, I, I, I, innych, I, I, i, I, i, i, I, i, I, innych, I, i, i, I, i, i, i, i, i, i, innego, I, I]

如果不应用Character.toLowerCase,单独计算大小写字母:

char letter = word.charAt(0);

那么冠军是:

Most frequent: n; frequency = 38
[niej, nic, nie, nie, noc, nim, na, noc, nie, nawrotem, nie, noc, nim, nagle, nie, nigdy, nie, nigdy, nigdy, nich, nie, nie, noc, nie, nim, nic, nic, ni, niczyjego, nic, nie, niewiadomosc, nie, nicosc, na, naglych, niebie, nie]

可以使用 Stream API 输出前 10 个最常见的首字母,以按列表的大小对地图中的条目进行排序:

final int mx = maxFreq;
map.entrySet().stream()
    .sorted(Comparator.<Map.Entry<Character, LinkedList<String>>>comparingInt(e -> e.getValue().size())
        .reversed()
        .thenComparing(Map.Entry.comparingByKey())
    )
    .limit(10)
    .forEach(e -> System.out.println(e.getKey() + " = " + e.getValue().size()));

输出(不区分大小写检查):

i = 47
n = 42
s = 36
w = 34
d = 31
m = 30
p = 28
t = 26
z = 25
c = 20

【讨论】:

感谢您的精彩帖子。有没有办法消除解决方案中的重复项,从而避免 i i i i i 等。

以上是关于创建 HashMap,其中键等于文本中最常见的第一个字母,值是从该字母开始的所有单词的链表的主要内容,如果未能解决你的问题,请参考以下文章

找出缺失整数

用排除法计算 SQL 表中最常见的单词

如何设置动态文本的按钮宽度等于div中最宽的按钮?

程序员面试中最常见的27个问题,拿走不谢!

插入 HashMap 会更改地图中每个键的值 [重复]

查找文本中最常见的词