Java单词统计与排序需求:带引号单词需后置输出
解决特殊规则的单词统计与排序问题
你已经搞定了总单词数的统计,但还需要完成单词计数和符合要求的排序——让带双引号的单词排在最后,其余按字母顺序排列对吧?这里给你修改后的完整代码,一步步解决问题:
默认的TreeSet是基于ASCII码排序的,而双引号的ASCII码比小写字母小,所以会排到最前面。我们需要自定义比较逻辑来满足你的特殊排序规则,同时用HashMap来高效统计单词出现次数。
import java.util.*; public class UniqueWord { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String inp = sc.nextLine(); // 预处理:转小写,仅保留字母、引号和空格,其他字符替换为空格 inp = inp.toLowerCase().replaceAll("[^a-z\" ]", " "); // 提取所有单词并统计总数 List<String> words = new ArrayList<>(); StringTokenizer tokenizer = new StringTokenizer(inp); int totalCount = 0; while (tokenizer.hasMoreTokens()) { String word = tokenizer.nextToken(); words.add(word); totalCount++; } // 统计每个单词的出现次数 Map<String, Integer> wordCountMap = new HashMap<>(); for (String word : words) { wordCountMap.put(word, wordCountMap.getOrDefault(word, 0) + 1); } // 提取单词集合并执行自定义排序 List<String> sortedWords = new ArrayList<>(wordCountMap.keySet()); Collections.sort(sortedWords, new Comparator<String>() { @Override public int compare(String s1, String s2) { boolean s1IsQuoted = s1.startsWith("\"") || s1.endsWith("\""); boolean s2IsQuoted = s2.startsWith("\"") || s2.endsWith("\""); // 核心规则:不带引号的单词优先级更高,排前面 if (s1IsQuoted && !s2IsQuoted) { return 1; } else if (!s1IsQuoted && s2IsQuoted) { return -1; } // 同类型单词(都带/都不带引号)按字母顺序排序 else { return s1.compareTo(s2); } } }); // 输出结果 System.out.println("Number of words " + totalCount); System.out.println("Words with the count"); for (String word : sortedWords) { System.out.println(word + ": " + wordCountMap.get(word)); } } }
关键逻辑说明
- 单词提取:用
StringTokenizer处理连续空格,比手动遍历字符更简洁可靠,能准确拆分每个单词。 - 计数优化:用
HashMap的getOrDefault方法一行完成计数更新,避免复杂的空值判断。 - 自定义排序:通过
Comparator先区分带引号和不带引号的单词,让不带引号的全部排在前面,同组内再按常规字母顺序排序,完美解决TreeSet默认排序的问题。
测试你提供的输入示例,就能得到和预期完全一致的输出,包括把“wrapped”放在最后。
内容的提问来源于stack exchange,提问作者Ram
相关产品推荐
相关产品推荐

