单词计数问题是大数据领域中最广泛涵盖的问题之一;它类似于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
}
如果你的数据集太大无法建立内存哈希表,可以像下面这样进行计数:
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框架,以便在机器集群上进行单词计数。
听说当处理的数据集过于庞大时,在分布式环境下执行操作并不能起到很大帮助,因为传输时间会超过计数时间,对于单词计数这种情况,所有内容最终仍然必须“重新组合在一起”,所以您必须使用一些非常复杂的技术,我猜在研究论文中可能可以找到。
补充说明:
问题提出者要求在Java中提供输入标记化的示例。以下是最简单的方法:
import java.util.Scanner;
public class WordGenerator {
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
产生
hey
moe
nyuk
soitenly
why
woo
输出中有一个空白行;我会让你想办法去掉它。 :)