统计词频
难度:
标签:
题目描述
写一个 bash 脚本以统计一个文本文件 words.txt
中每个单词出现的频率。
为了简单起见,你可以假设:
words.txt
只包括小写字母和' '
。- 每个单词只由小写字母组成。
- 单词间由一个或多个空格字符分隔。
示例:
假设 words.txt
内容如下:
the day is sunny the the the sunny is is
你的脚本应当输出(以词频降序排列):
the 4 is 3 sunny 2 day 1
说明:
- 不要担心词频相同的单词的排序问题,每个单词出现的频率都是唯一的。
- 你可以使用一行 Unix pipes 实现吗?
代码结果
运行时间: 0 ms, 内存: 3.7 MB
/*
* 思路:
* 1. 读取文件内容并按空格拆分成单词。
* 2. 使用流操作和Collectors计算每个单词的出现次数。
* 3. 使用流排序并输出结果。
*/
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.stream.*;
public class WordFrequencyStream {
public static void main(String[] args) throws IOException {
List<String> lines = Files.readAllLines(Paths.get("words.txt"));
lines.stream()
.flatMap(line -> Arrays.stream(line.split("\s+")))
.collect(Collectors.groupingBy(word -> word, Collectors.counting()))
.entrySet()
.stream()
.sorted(Map.Entry.<String, Long>comparingByValue().reversed())
.forEach(e -> System.out.println(e.getKey() + " " + e.getValue()));
}
}
解释
方法:
该题解使用了Unix管道和一系列命令来统计文本文件中单词的频率。具体步骤如下:
1. 使用`cat`命令读取文件内容
2. 使用`tr`命令将所有空格字符替换为换行符,这样每个单词就会独占一行
3. 使用`sort -r`命令按字典序反向排序所有单词
4. 使用`uniq -c`命令统计每个单词出现的次数,并在每行行首显示频次
5. 使用`sort -r`命令按频次由高到低排序
6. 使用`awk`命令调整输出格式,使其符合题目要求
时间复杂度:
平均情况:O(nlogn),最坏情况:O(n^2)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在处理单词时选择使用`tr -s " " "\n"`命令将空格替换为换行符?这样做有什么具体的好处吗?
▷🦆
在使用`sort -r`进行字典序反向排序之前,为什么不直接进行词频统计?排序这一步的目的是什么?
▷🦆
在统计单词频率时,`uniq -c`命令是如何确保正确计数的?这是否意味着输入必须先排序?
▷🦆
您提到的第二次使用`sort -r`来按频次排序,是否存在更高效的排序方法考虑到`uniq -c`已经提供了部分组织好的数据?
▷