美国语言协会对美国人日常使用的英语单词做了一份详细的统计,按照日常使用的频率做成了一张表,称为COCA词频表。排名越低的单词使用频率越高,该表可以用来统计词汇量。
如果你的词汇量约为6000,那么这张表频率6000以下的单词你应该基本都认识。(不过国内教育平时学的单词未必就是他们常用的,只能说大部分重合)
我一直有个想法,要是能用COCA词频表统计一本小说中所有的词汇都是什么等级的,然后根据自己的词汇量,就能大致确定这本小说是什么难度,自己能不能读了。
学习了C++的容器和标准库算法后,我发现这个想法很容易实现,于是写了个能够统计文本词频的小工具。现在只实现了基本功能,写得比较糙。还有很多要改进的地方,随着以后的学习,感觉这个工具还是可以再深挖的。
v0.1
1.可逐个分析文本中的每一个单词并得到其COCA词频,生成统计报告。
2.仅支持txt。
实现的重点主要分三块。
(1)COCA词典的建立
首先建立出COCA词典。我使用了恶魔的奶爸公众号提供的txt格式的COCA词频表,这张表是经过处理的,每行只有一个单词和对应的频率,所以读取起来很方便。
读取文本后,用map容器来建立“单词——频率”的一对一映射。
要注意的是有些单词因为使用意思和词性的不同,统计表里会出现两个频率,也就是熟词的偏僻意思。我只取了较低的那个为准,因为你读文本时,虽然可能不是真正的意思但起码这个单词是认识的,而且这种情况总体来说比较少见,所以影响不大。
存储时我用了26组map,一个首字母存一组,单词查询时按首字母查找。可能有更有效率的办法。
(2)单词的获取和处理
使用get()方法逐个获取文本的字符。
使用vector容器存储读到的文本内容。如果是字母或连字符就push进去,如果不是,就意味着一个单词读完了,接着开始处理,把读到的文本内容assign到一个字符串中组成完整的单词,然后根据其首字母查找词频。
每个单词查到词频后,使用自定义的frequency_classify()区分它在什么范围,再用word_frequency_analyze()统计在不同等级的分布。
最后报告结果,显示出每个等级的百分比。
(3)单词的修正
首先是分析过的单词不会再分析第二遍,因为一般原文中像I,he,she,it,a,this,that这种特别常见的词还是很多的,如果每个都统计进去,会导致不同文章看到的结果都是高频词占到80%,90%。应该以单词的种类为准,而不是数量。
其次有很多单词的变形COCA词频表是不统计的,像许多单词的过去式,复数,进行时等,还有was,were,has,had等。所以我单独加了word_usual_recheck()和word_form_recheck()两个函数来检查是否有这些情况,如果有变形的话,就变为原型再尝试查找一次。但是这样做相当于手动修正,不能覆盖到所有情况,比如有些单词的变形并不遵循传统。
我先用了乔布斯斯坦福大学的演讲稿测试。测试结果:
总共分析了869个单词,77.45%的单词都找到了,且分布在4000以下,可见演讲稿使用的绝大多数的单词都是极其常用的单词,有4000以上的词汇量就基本能读懂。
我再测试了一下《小王子》的原文。
约70%的单词都找到了,且分布在4000以下,再加上4000-8000之间的,总共有接近80%的单词是六七千以下的级别。
为了对比,我再随便找了一篇纽约客上的文章测试。
可以看到,高频词的比例明显降低了一些,约有10%的单词是8000以上的级别,还有更多的单词找不到了,说明出现了许多单词的变形,当然也可能包括人名,毕竟是讨论政治的文章,还有小部分可能是超出20000。
以下是代码。
TextVolcabularyAnalyzer.cpp
1 #include
2 #include
3 #include <string>
4 #include
5 #include
6 #include
7 #include
8 #include