我们常常说“二八原则”或“20/80原则”,例如,80%的财富集中在20%的人手中、80%的用户只使用20%的功能、20%的用户贡献了80%的访问量,等等。如果把所有的单词(字)放在一起看呢?会不会20%的词(字)占了80%的出现次数?答案是肯定的。
1932年,哈佛大学的语言学专家Zipf在研究英文单词出现的频率时,发现如果把单词出现的频率按由大到小的顺序排列,则每个单词出现的频率与它的名次的常数次幂存在简单的反比关系,这种分布就称为Zipf定律,它表明在英语单词中,只有极少数的词被经常使用,而绝大多数词很少被使用.实际上,包括汉语在内的许多国家的语言都有这种特点。这个定律后来在很多领域得到了同样的验证,包括网站的访问者数量、城镇的大小和每个国家公司的数量等。
本题要求你对zipf定律进行简单验证。
输入:
一系列文本,以空白分隔每个英文单词。忽略单词大小写,并不考虑各种特殊字符。
(s = s.replaceAll("[\\d\",!.:;?()`'*-]", "");)
输出:
逆序输出出现频率最高的前十个单词,以及对应的出现次数。(相同出现次数的,按字母表逆序输出)
样例输入:
Communist Manifesto(共产党宣言)
样例输出:
the:1141↵
of:779↵
and:345↵
in:287↵
to:261↵
a:164↵
is:135↵
that:125↵
by:111↵
with:99↵
import java.util.Arrays;
/*
* 齐普夫(Zipf)定律
* 1932年,哈佛大学的语言学专家Zipf在研究英文单词出现的频率时,
* 发现如果把单词出现的频率按由大到小的顺序排列,则每个单词出现
* 的频率与它的名次的常数次幂存在简单的反比关系,这种分布就称为Zipf定律
*/
public class Main {
public static void main(String[] args) throws Exception {
String strRead = StdIn.readAll();
/*字符处理begin*/
//第一步.统一转换为小写字母
strRead = strRead.toLowerCase();
//第二步.替换文章中的标点符号
strRead = strRead.replaceAll("[\\d\",!.:;?()`'*-]","");
//第三步.按空格或回车换行截取单词(\\s表示 空格,回车,换行等空白符+表示多个)
String[] arrWord = strRead.split("\\s+");
/*字符处理end*/
//对字符串排序
Arrays.sort(arrWord);
Frequency[] arrFrequency = new Frequency[arrWord.length];
int i = 0;
for(int j=0;j<arrWord.length;j++){
if((j==0)||(!arrWord[j].equals(arrWord[(j-1)])))
arrFrequency[i++] = new Frequency(arrWord[j],arrWord.length,0);
arrFrequency[i-1].getCount();
}
//按出现的频次从大到小倒序输出
Arrays.sort(arrFrequency, 0, i);
for(int n=i-1;n>Math.max(i-10, 0);n--){
StdOut.println(arrFrequency[n]);
}
}
}
//定义统计频次类
class Frequency implements Comparable<Frequency>{
private String word;
private int maxCount;
private int count;
//定义构造方法
public Frequency(String word,int maxCount,int count){
this.word = word;
this.maxCount = maxCount;
this.count = count;
}
public int getCount(){
return this.count;
}
//转换为字符串
public String toString(){
return this.word+":"+this.count;
}
//统计单词
public void countWord(){
if(count<maxCount){
count+=1;
}
}
@Override
public int compareTo(Frequency o) {
if(this.count>o.count) return 1;
if(this.count<o.count) return -1;
return 0;
}
}