前面通过实验,已经完成了批量文件处理和单文件的单字字频处理的功能,在此基础上, 我们便可以统计语料库的单字字频了.语料库实质就是一批文件的集合,通常为文本文件,所以语料库字频的统计也就是批量文件字频的统计了.语料库单字字频统计的基本思路是:利用File对象的String list()或File[] listFiles方法,获取语料库中的所有文件的文件名 或文件数量,然后循环读取统计每一个文件,并将每个文件的统计结果添加到一个存储字频的动态数组中(这个数组的每个元素的下标对应GB2312-80中的一个汉字,数组每个元素的值对应该汉字的字频),统计完毕,输出出现的每个符合要求的汉字及其字频,并计算出现的字型(word type)总数.下面的代码实现了这个功能.由于只是一个小小的实验,没有考虑太多程序质量的问题,比如,这段代码好象只能处理类文本文件,象二进制文件不能处理,会产生数据溢出的错误,另外,感觉代码比较乱,还需要继续优化.如果有高手在此路过,请多指教.
import java.io.*;
public class BatWordFreq {
public static void main(String args[]) throws IOException{
File newDir=new File("d://java//test");//创建文件目录对象
File newFileFre=new File("d://java//WordFre.dat");//创建输出文件对象
newFileFre.createNewFile();
int n=0;// 设置字型数的初始值
String[] files=newDir.list();//创建文件夹中的文件列表
int filesNum=files.length;//获取文件夹中文件的个数.
int[] wordF=new int[6768];
RandomAccessFile fileW=new RandomAccessFile(newFileFre,"rw");
//循环处理每个文件
for(int i=0;i<filesNum;i++)
{
File newFileR=new File(newDir,files[i]);
RandomAccessFile fileR=new RandomAccessFile(newFileR,"r");
long fileLength=newFileR.length();//获取文件的字节长度
//int[] wordF=new int[6768];
for(int j=0;j<fileLength;j++)
{
int c1=fileR.read();
if (c1<128)continue;
if(c1<176){int c2=fileR.read();continue;}
int c2=fileR.read();
int id=(c1-176)*94+(c2-161);
wordF[id]++;
};
};
//计算语料库里的字型的数量
for(int m=0;m<6768;m++){
if (wordF[m]!=0)n++;//计算出现的不同的字的数量.
};
//输出字型及其对应的字频
for(int id=0;id<6768;id++){
if (wordF[id]>0)
{
int d1=(id/94)+176;
int d2=(id%94)+161;
String word1=Integer.toString(d1, 2);
String word2=Integer.toString(d2, 2);
String word=word1+word2;
long wordAsc=Long.parseLong(word,2);//将二进制字符串转换为ASCII码
fileW.writeLong(wordAsc);//输出汉字字符
fileW.writeChars(wordF[id]+" ");
//fileW.writeChars(wordF[id]+" "+wordAsc);// 输出字频及ASCII编码
fileW.writeBytes("/r/n");//换行
}
};
System.out.println(n);//输出总的字形数(即有多少个符合要求的不同的字)
}
}