单词 统计
第1步:输出单个文件中的前 N 个最常出现的英语单词。
功能1:输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列。
功能2: 指定文件目录,对目录下每一个文件执行统计的操作。
功能3:指定文件目录,是会递归遍历目录下的所有子目录的文件进行统计单词的功能。
功能4:输出出现次数最多的前 n 个单词,
例如, 提示统计统计前多少名:输入10。 就是输出最常出现单词的前 10 名。 当没有指明数量的时候,我们默认列出所有单词的频率。
第2步:第二步: 支持 stop words
在一本小说里, 频率出现最高的单词一般都是 "a", "it", "the", "and", "this", 这些词, 可以做一个 stop word 文件 (停词表), 在统计词汇的时候,跳过这些词。 我们把这个文件叫 "stopwords.txt" file.
第三步: 想看看常用的短语是什么, 怎么办呢?
先定义短语:"两个或多个英语单词, 它们之间只有空格分隔". 请看下面的例子:
hello world //这是一个短语
hello, world //这不是一个短语
同一频率的词组, 按照字典序来排列。
第四步:把动词形态都统一之后再计数。
想找到常用的单词和短语,但是发现英语动词经常有时态和语态的变化,导致同一个词,同一个短语却被认为是不同的。 怎么解决这个问题呢?
假设我们有这样一个文本文件,这个文件的每一行都是这样构成:
动词原型 动词变形1 动词变形2... ,词之间用空格分开。
e.g. 动词 TAKE 有下面的各种变形:take takes took taken taking
我们希望在实现上面的各种功能的时候,有一个选项, 就是把动词的各种变形都归为它的原型来统计。
功能 支持动词形态的归一化
package letter3; import java.util.*; import java.util.regex.*; import java.io.*; import java.text.NumberFormat; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.text.DecimalFormat; import java.util.HashMap; import java.util.Map; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; public class Main { public static void main (String args[]) throws IOException { int k = 0; do { Scanner sc = new Scanner(System.in); System.out.println("输入数字实现数字代表功能:"); System.out.println("1.统计字母数量,计算字母所占百分比;"); System.out.println("2.统计单词数量并展示;"); System.out.println("3.显示要求排名的单词;"); int number = sc.nextInt(); if(number == 1) { one(); } else if(number == 2) { two(); } else if(number == 3) { three(); } else { System.out.println("输入错误!"); } System.out.println("输入是否继续(1为继续,0为退出):"); k = sc.nextInt(); }while(k == 1); } private static String formattedDecimalToPercentage(double decimal) { //获取格式化对象 NumberFormat nt = NumberFormat.getPercentInstance(); //设置百分数精确度2即保留两位小数 nt.setMinimumFractionDigits(2); return nt.format(decimal); } public static void one() { String a1; char a='A'; int a2[]=new int[27]; char b1[]=new char[26]; char b2[]=new char[26]; for(int i=0;i<26;i++) { b1[i]=a; b2[i]=(char)(a+32); a++; } /*for(int i=0;i<26;i++) { System.out.println(b1[i]); System.out.println(b2[i]); }*/ try { BufferedReader in = new BufferedReader(new FileReader("D:\\应用\\java_workplace\\word1\\piao.txt")); String str; while ((str = in.readLine()) != null) { char[] d=str.toCharArray(); for(int i=0;i<d.length-1;i++) { for(int j=0;j<26;j++) { if(b1[j]==d[i]||b2[j]==d[i]) { a2[j]++; } } } } a2[26]=0; for(int i=0;i<26;i++) { a2[26]=a2[i]+a2[26]; } for(int i=0;i<26;i++) { System.out.print(b1[i]); System.out.print("和"); System.out.print(b2[i]); System.out.print("出现的次数为:"); System.out.println(a2[i]); double d=(double)((double)a2[i]/(double)a2[26]); String result2=formattedDecimalToPercentage(d); System.out.println("result = "+result2); } } catch (IOException e) {} } public static void two() throws IOException { BufferedReader buf=new BufferedReader(new FileReader("D:\\应用\\java_workplace\\word1\\piao.txt")); System.out.println("Read under this dir English.txt"); StringBuffer sbuf=new StringBuffer();//缓冲字符串 String line=null; while((line=buf.readLine())!=null){ sbuf.append(line);//追加到缓冲字符串中 } buf.close();//读取结束 Pattern expression=Pattern.compile("[a-zA-Z]+");//定义正则表达式匹配单词 String string1=sbuf.toString().toLowerCase();//转换成小写 Matcher matcher=expression.matcher(string1);//定义string1的匹配器 TreeMap myTreeMap=new TreeMap();//创建树映射 存放键/值对 int n=0;//文章中单词总数 Object word=null;//文章中的单词 Object num=null;//出现的次数 while(matcher.find()) {//是否匹配单词 word=matcher.group();//得到一个单词-树映射的键 n++;//单词数加1 if(myTreeMap.containsKey(word)) {//如果包含该键,单词出现过 num=myTreeMap.get(word);//得到单词出现的次数 Integer count=(Integer)num;//强制转化 myTreeMap.put(word,new Integer(count.intValue()+1)); } else { myTreeMap.put(word,new Integer(1));//否则单词第一次出现,添加到映射中 } } System.out.println("统计分析如下:"); System.out.println("文章中单词总数"+n+"个"); System.out.println("txt中不同单词"+myTreeMap.size()+"个"); Iterator iter=myTreeMap.keySet().iterator();//得到树映射键集合的迭代器 Object key=null; while(iter.hasNext()){//使用迭代器遍历树映射的键 key=iter.next(); System.out.println((String)key+":"+myTreeMap.get(key)); } } public static void three() throws IOException { Scanner sc = new Scanner(System.in); System.out.println("请输入从第几到第几?"); int n = sc.nextInt(); int m = sc.nextInt(); List<Integer> list=new ArrayList<>(); DecimalFormat df=new DecimalFormat("######0.00"); File f = new File("D:\\应用\\java_workplace\\word1\\piao.txt"); FileInputStream fip = new FileInputStream(f); InputStreamReader reader = new InputStreamReader(fip, "gbk"); StringBuffer sb = new StringBuffer(); while (reader.ready()) { sb.append((char) reader.read()); } reader.close(); fip.close(); int i; String A=sb.toString(); String M="abcdefghijklmnopqrstuvwxyz"; String temp = ""; char NUM[]=new char[A.length()]; char Z[]=new char[26]; int X[]=new int[26]; int MAX=0; Z=M.toCharArray(); for(int k=0;k<26;k++) { X[k]=0; for(i=0;i<A.length();i++) { NUM[i]=A.charAt(i); if(Z[k]==NUM[i]||Z[k]==ch(NUM[i])) { X[k]++; } } } StringTokenizer st = new StringTokenizer(sb.toString(),",.! \n"); String []a1=StatList(sb.toString()); int []b1 = StatList1(sb.toString()); String []c1=StatList(sb.toString()); for(i = 0;i < a1.length-1;i++) for(int j = 0 ;j < a1.length-1-i; j++) { if(b1[j]<b1[j+1]) { int temp6 = b1[j]; b1[j] = b1[j+1]; b1[j+1] = temp6; String temp7 = a1[j]; a1[j] = a1[j+1]; a1[j+1] = temp7; } } for(int j = 0 ;j < a1.length-1-i; j++) { System.out.println("输入无用词:"); Scanner sp = new Scanner(System.in); } for(i = n+1;i <= m+1;i++) { int z = 0; for(int q = 0; q<a1.length-1; q++) { if(c1[q] == a1[i]) { z = 0; } } if( z == 1) { System.out.println("单词:"+a1[i]+" 且出现的次数:"+b1[i]); } } } static char ch(char c) { if(!(c>=97&&c<=122)) c+=32; return c; } static String[] StatList(String str) { StringBuffer sb = new StringBuffer(); HashMap<String ,Integer> has = new HashMap<String ,Integer> (); // 打开一个哈希表 String[] slist = str.split("\\W+"); int sum=0; int sum1=0; for (int i = 0; i < slist.length; i++) { if (!has.containsKey(slist[i])) { // 若尚无此单词 has.put(slist[i], 1); sum++; sum1++; } else {//如果有,就在将次数加1 Integer nCounts = has.get(slist[i]); has.put(slist[i],nCounts+1 ); } } int temp=0; int temp1=0; String []a=new String[sum]; int []b=new int[sum1]; Iterator iterator = has.keySet().iterator(); while(iterator.hasNext()) { String word = (String) iterator.next(); a[temp]=word; temp++; } return a; } static int[] StatList1(String str) { StringBuffer sb = new StringBuffer(); HashMap<String ,Integer> has = new HashMap<String ,Integer> (); // 打开一个哈希表 String[] slist = str.split("\\W+"); int sum=0; int sum1=0; for (int i = 0; i < slist.length; i++) { if (!has.containsKey(slist[i])) { // 若尚无此单词 has.put(slist[i], 1); sum++; sum1++; } else {//如果有,就在将次数加1 Integer nCounts = has.get(slist[i]); has.put(slist[i],nCounts+1 ); } } int temp=0; int temp1=0; String []a=new String[sum]; int []b=new int[sum1]; Iterator iterator = has.keySet().iterator(); while(iterator.hasNext()) { String word = (String) iterator.next(); b[temp1]=has.get(word); temp1++; } return b; } }
思路:
先实现读取文件,将txt文档中的文章读取出来,然后将单词转换为小写,对比单词计数,输出结果
总结:
对于文件读取不熟悉,之前一直研究数据库的增删改查,要用文件了很不熟悉,文件读取都弄了很长时间。
学过的东西要及时复习,不能等忘了在来做。