字数统计问题是大数据世界中覆盖最广泛的问题之一;它有点像 Hadoop 等框架的 Hello World。您可以在整个网络上找到有关此问题的大量信息。
无论如何,我会给你一些想法。
首先,900000 个单词可能仍然小到可以为其构建哈希图,所以不要忽视明显的内存方法。你说伪代码很好,所以:
h = new HashMap<String, Integer>();
for each word w picked up while tokenizing the file {
h[w] = w in h ? h[w]++ : 1
}
现在,一旦您的数据集太大而无法构建内存中的 hashmap,您可以像这样进行计数:
Tokenize into words writing each word to a single line in a file
Use the Unix sort command to produce the next file
Count as you traverse the sorted file
这三个步骤进入 Unix 管道。让操作系统在这里为您完成工作。
现在,随着您获得更多数据,您希望引入像 hadoop 这样的 map-reduce 框架来对机器集群进行字数统计。
现在,我听说当你进入非常大的数据集时,在分布式环境中做事不再有帮助,因为传输时间超过了计数时间,而且在你的字数统计的情况下,一切都必须“重新组合在一起”无论如何”,所以你必须使用一些我怀疑你可以在研究论文中找到的非常复杂的技术。
附录
OP 要求提供一个在 Java 中对输入进行标记的示例。这是最简单的方法:
import java.util.Scanner;
public class WordGenerator {
/**
* Tokenizes standard input into words, writing each word to standard output,
* on per line. Because it reads from standard input and writes to standard
* output, it can easily be used in a pipeline combined with sort, uniq, and
* any other such application.
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
System.out.println(input.next().toLowerCase());
}
}
}
现在这里是一个使用它的例子:
echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator
这输出
hey
moe!
woo
woo
woo
nyuk-nyuk
why
soitenly.
hey.
您可以将此标记器与 sort 和 uniq 结合起来,如下所示:
echo -e "Hey Moe! Woo\nwoo woo nyuk-nyuk why soitenly. Hey." | java WordGenerator | sort | uniq
屈服
hey
hey.
moe!
nyuk-nyuk
soitenly.
why
woo
现在,如果您只想保留字母并丢弃所有标点符号、数字和其他字符,请将扫描仪定义行更改为:
Scanner input = new Scanner(System.in).useDelimiter(Pattern.compile("\\P{L}"));
现在
echo -e "Hey Moe! Woo\nwoo woo^nyuk-nyuk why#2soitenly. Hey." | java WordGenerator | sort | uniq
产量
hey
moe
nyuk
soitenly
why
woo
输出中有一个空行;我会让你弄清楚如何敲打它。:)