从一个英文字符串中找出每个单词出现的频率

本文介绍了一个简单的Java程序,该程序通过使用HashMap来统计并打印出给定字符串中每个字符出现的次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


import java.util.*;

public class Lookup{
    public static void main(String[] args){
        String s = "the instruction set of the Java virtual machine distinguishes its operand types using instructions intended to operate on values of specific types";
        String[] word = s.split(" ");
        Map<String,Integer> m = new HashMap<String,Integer>();
        //用word初使化m,m中包含了所有不重复的单词
        for(int j=0;j<word.length;j++){
            m.put(word[j],0);
        }
        
        Set<String> set = m.keySet(); 
        //用word中的每个单词与m中的单词比较,发现相同的就统计一次    
        for(int i=0;i<word.length;i++){
        Iterator<String> it = set.iterator();
         while(it.hasNext()){
              String k = it.next();
              if(word[i].equals(k)){
                    int c = m.get(k);                  
                    c++;
                    m.put(word[i],c);
                }
            }                          
        }
        System.out.println(m);
    }
}

 

<think>嗯,用户想用Java实现统计一段话中出现频率最高的10个单词的代码示例或者教程。首先,我得回忆一下Java中处理文本和集合的相关知识。我记得处理单词统计通常会用HashMap来记录每个单词的出现次数,然后对结果进行排序。 首先,用户需要分割文本中的单词。用split方法或者StringTokenizer可能比较合适。不过split方法的正则表达式可能不够灵活,比如需要处理各种空白符或者标点符号。或者可能需要用正则表达式来过滤掉非字母字符,比如用replaceAll("[^a-zA-Z ]", "")来替换掉所有非字母的字符,但这样可能会把带连字符的单词也处理了,不过用户的需求可能不需要那么精确,先这样处理应该可以。 然后,分割成单词之后,遍历每个单词,转成小写,这样避免大小写造成的重复统计。例如,"Hello"和"hello"应该算作同一个单词。所以需要调用toLowerCase()方法。 接下来用HashMap来统计频率。遍历每个单词,如果单词已经在map中,就增加计数,否则放入map并设置计数为1。 统计完之后,需要根据词频排序,然后取前10个。但是HashMap本身是无序的,所以需要将entrySet转换成List,然后用Collections.sort并自定义一个比较器,按照值(计数)降序排列。这里需要注意,比较的时候要使用Comparator的comparing方法,并且使用reversed()来降序。 排序后的列表取前10个元素,可以用subList方法或者循环添加前10个。 不过要考虑处理文本为空或者单词数量不足10个的情况,这时候可能需要处理异常或者返回所有存在的单词。 然后,用户给的示例代码中的MapReduce例子可能不太适合单个Java程序的情况,但可以简化处理流程。比如不需要MapReduce框架,直接用单线程处理。 还有,用户提供的引用中有提到使用StringTokenizer来分割单词,这可能比split更高效,因为StringTokenizer会按空格、制表符、换行符等进行分割,不需要写复杂的正则表达式。所以在代码中使用StringTokenizer可能更好。 接下来,写代码的大致步骤: 1. 读取输入文本,或者直接处理给定的字符串。 2. 清洗文本,去掉标点符号,转为小写。 3. 分割成单词。 4. 统计每个单词频率。 5. 将统计结果排序。 6. 取前10个结果。 可能的代码结构: 使用BufferedReader来读取文件,或者直接处理字符串。例如,用户可能想处理一个字符串而不是文件,所以可以示例中使用字符串输入。 示例代码: 先定义一个测试字符串,比如: String text = "..."; 然后处理: text = text.replaceAll("[^a-zA-Z ]", "").toLowerCase(); StringTokenizer tokenizer = new StringTokenizer(text, " \t\n\r\f,.;:!?"); Map<String, Integer> wordCount = new HashMap<>(); while (tokenizer.hasMoreTokens()) { String word = tokenizer.nextToken(); wordCount.put(word, wordCount.getOrDefault(word, 0) + 1); } 然后,将entrySet转为List,排序: List<Map.Entry<String, Integer>> list = new ArrayList<>(wordCount.entrySet()); Collections.sort(list, (a, b) -> b.getValue().compareTo(a.getValue())); 然后取前10个: List<Map.Entry<String, Integer>> top10 = list.subList(0, Math.min(10, list.size())); 最后遍历输出。 不过这里需要注意,如果有多个单词频率相同的情况,可能需要稳定排序或者其他方式处理,但用户可能不需要考虑这个,按出现顺序处理即可。 另外,用户提供的引用中的代码示例使用了MapReduce,但用户的问题可能不需要分布式处理,所以单机版的代码更合适。 现在,把这些步骤整合成代码示例。需要注意处理可能的异常,比如空文本,或者分割后的单词列表为空。 可能还需要处理单词的边界情况,比如多个连续空格,或者标点符号紧接在单词后面,例如"word."会被处理成"word",但需要替换掉非字母字符,所以用replaceAll("[^a-zA-Z ]", "")会将标点替换为空,从而正确分割。 这样,最终的代码应该能正确统计单词频率,并输出前10个高频词。 此外,用户可能需要完整的可运行示例,所以可以提供一个完整的main函数,包括测试字符串和输出结果。 最后,验证代码是否正确,比如测试文本中的单词是否被正确分割,统计是否正确,排序是否降序,是否取前10个。 可能的问题点:处理标点符号是否正确,是否考虑了所有分割情况,排序是否正确,是否处理了大小写。 现在,将这些思考整理成一个步骤清晰的回答,并提供代码示例。同时,根据用户提供的引用,其中引用[2]提到了MapReduce的例子,但用户可能不需要分布式处理,所以可以说明在单机环境下使用HashMap和排序的方法,并引用相关步骤对应的引用内容。 可能生成的相关问题包括如何处理大小写、如何处理标点符号、如何优化性能,或者如何处理并列排名的情况。这些可以作为相关问题列出来。</think>以下是用Java实现统计文本中出现频率最高的10个单词的代码示例及分步说明: ### 实现步骤 1. **文本预处理**:去除标点符号、统一小写 2. **单词分割**:使用`StringTokenizer`按空格分割 3. **频率统计**:通过`HashMap`存储单词计数 4. **结果排序**:转换为列表按值降序排序 5. **获取前10**:截取排序后的前10个元素 ```java import java.util.*; import java.util.stream.Collectors; public class WordFrequencyCounter { public static void main(String[] args) { String text = "Natural language processing (NLP) is a subfield of computer science..."; // 输入文本 // 1. 清洗文本并转为小写 String cleanText = text.replaceAll("[^a-zA-Z ]", "").toLowerCase(); // 2. 分割单词 StringTokenizer tokenizer = new StringTokenizer(cleanText, " \t\n\r\f"); Map<String, Integer> wordCountMap = new HashMap<>(); // 3. 统计频率 while (tokenizer.hasMoreTokens()) { String word = tokenizer.nextToken(); wordCountMap.put(word, wordCountMap.getOrDefault(word, 0) + 1); } // 4. 排序并取前10 List<Map.Entry<String, Integer>> sortedList = wordCountMap.entrySet() .stream() .sorted(Map.Entry.<String, Integer>comparingByValue().reversed()) .limit(10) .collect(Collectors.toList()); // 5. 输出结果 System.out.println("Top 10 Frequent Words:"); sortedList.forEach(entry -> System.out.println(entry.getKey() + ": " + entry.getValue())); } } ``` ### 关键点说明 - 正则表达式`[^a-zA-Z ]`保留字母和空格,过滤标点符号[^2] - `StringTokenizer`自动处理多种空白符分割[^2] - `getOrDefault`方法简化计数逻辑 - Java Stream API实现高效排序和结果截取[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值