单词统计续
第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
我们希望在实现上面的各种功能的时候,有一个选项, 就是把动词的各种变形都归为它的原型来统计。
功能 支持动词形态的归一化
【思路分析】
这个主要是规范代码,将之前写过的功能封装之后是最简洁的,方便调用,这也是这次检验的目的。
讲真,这个代码,自己确实没写出来,但是也有一些想法:
按照要求,整个代码的实现肯定是有一个大的选择结构——菜单栏功能,选择对应的选项可以进入不同的功能,如果将四个功能单独封装,这个主程序代码将会非常简单。
在功能方面,第一个功能之前写过,主要是第二、三、四功能,遍历文件,统计,都有对应的代码
stop words这块儿,将常用单词放入文件或数组,统计文案时进行对比,如果有就直接跳过,进行下一个进行比对,没有则进行统计。
第三步和第四步对于短语的定义感觉比较麻烦,要考虑到的东西比较多,因为不是用空格隔开的两个单词都是短语,涉及到一些词库,还有单词的不同形态,这些需要大量的词库进行比对。
【部分功能代码(能力有限,参考同学代码)】
package tongjizimn; 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.util.Scanner; //哈利波特单词统计 public class Pipei { public static Map<String,Integer> map1=new HashMap<String,Integer>(); static int g_Wordcount[]=new int[27]; static int g_Num[]=new int[27]; static String []unUse=new String[] { "it", "in", "to", "of", "the", "and", "that", "for" }; public static void main(String arg[]) { //daoruFiles("piao.txt","tongji"); traverseFolder2("E:\\piao"); } public static void daoruFiles(String a,String dc) { System.out.println("1:统计前十单词次数最多的单词;2:统计字母频率; 3:统计所有单词出现频率"); int number; Scanner sc=new Scanner(System.in); System.out.println("请输入你要选择的功能"); number=sc.nextInt(); map1.clear(); try { daoru(a); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } String sz[]; Integer num[]; final int MAXNUM=10; //统计的单词出现最多的前n个的个数 for(int i=0;i<g_Wordcount.length;i++) { g_Wordcount[i]=0; g_Num[i]=i; } sz=new String[MAXNUM+1]; num=new Integer[MAXNUM+1]; Pipei pipei=new Pipei(); int account =1; //Vector<String> ve1=new Vector<String>(); try { daoru(a); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } int g_run=0; for(g_run=0;g_run<MAXNUM+1;g_run++) { account=1; for(Map.Entry<String,Integer> it : Pipei.map1.entrySet()) { if(account==1) { sz[g_run]=it.getKey(); num[g_run]=it.getValue(); account=2; } if(account==0) { account=1; continue; } if(num[g_run]<it.getValue()) { sz[g_run]=it.getKey(); num[g_run]=it.getValue(); } if(number==3) System.out.println("英文单词: "+it.getKey()+" 该英文单词出现次数: "+it.getValue()); } Pipei.map1.remove(sz[g_run]); } int g_count=1; String tx1=new String(); String tx2=new String(); if(number==1) { for(int i=0;i<g_run;i++) { if(sz[i]==null) continue; if(sz[i].equals("")) continue; tx1+="出现次数第"+(g_count)+"多的单词为:"+sz[i]+"\t\t\t出现次数: "+num[i]+"\r\n"; System.out.println("出现次数第"+(g_count)+"多的单词为:"+sz[i]+"\t\t\t出现次数: "+num[i]); g_count++; } try { daochu(tx1,dc+"2.txt"); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } //------------------------------ int temp=g_Wordcount[0]; int numtemp=0; for(int i=0;i<26;i++) { for(int j=i;j<26;j++) { if(g_Wordcount[j]>g_Wordcount[i]) { temp=g_Wordcount[i]; g_Wordcount[i]=g_Wordcount[j]; g_Wordcount[j]=temp; numtemp=g_Num[i]; g_Num[i]=g_Num[j]; g_Num[j]=numtemp; } } } int sum=0; if(number==2) { for(int i=0;i<26;i++) { sum+=g_Wordcount[i]; } for(int i=0;i<26;i++) { char c=(char) ('a'+g_Num[i]); tx2+=c+":"+String.format("%.2f%% \r\n", (double)g_Wordcount[i]/sum*100); System.out.println(c+":"+String.format("%.2f%% \r\n", (double)g_Wordcount[i]/sum*100)); } try { daochu(tx2,dc+"1.txt"); } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } } //------------------------------ } public static void daoru(String s) throws IOException { File a=new File(s); FileInputStream b = new FileInputStream(a); InputStreamReader c=new InputStreamReader(b,"UTF-8"); String string2=new String(""); while(c.ready()) { char string1=(char) c.read(); if(WordNum(string1)>=0) { g_Wordcount[WordNum(string1)]+=1; } //------------------------ if(!isWord(string1)) { if(!isBaseWord(string2)) { if(map1.containsKey(string2.toLowerCase())) { Integer num1=map1.get(string2.toLowerCase())+1; map1.put(string2.toLowerCase(),num1); } else { Integer num1=1; map1.put(string2.toLowerCase(),num1); } } string2=""; } else { if(isInitWord(string1)) { string2+=string1; } } } if(!string2.isEmpty()) { if(!isBaseWord(string2)) { if(map1.containsKey(string2.toLowerCase())) { Integer num1=map1.get(string2.toLowerCase())+1; map1.put(string2.toLowerCase(),num1); } else { Integer num1=1; map1.put(string2.toLowerCase(),num1); } } string2=""; } c.close(); b.close(); } public static void daochu(String txt,String outfile) throws IOException { File fi=new File(outfile); FileOutputStream fop=new FileOutputStream(fi); OutputStreamWriter ops=new OutputStreamWriter(fop,"UTF-8"); ops.append(txt); ops.close(); fop.close(); } public static boolean isWord(char a) { if(a<='z'&&a>='a'||a<='Z'&&a>='A'||a=='\'') return true; return false; } public static boolean isInitWord(char a) { if(a<='z'&&a>='a'||a<='Z'&&a>='A'||a>'0'&&a<'9'||a=='\'') return true; return false; } public static boolean isBaseWord(String word) { for(int i=0;i<unUse.length;i++) { if(unUse[i].equals(word)||word.length()==1) return true; } return false; } public static int WordNum(char a) { if(a<='z'&&a>='a') return a-'a'; else if(a<='Z'&&a>='A') return a-'A'; return -1; } //----递归文件夹 public static void traverseFolder2(String path) { File file = new File(path); if (file.exists()) { File[] files = file.listFiles(); if (null == files || files.length == 0) { System.out.println("文件夹是空的!"); return; } else { for (File file2 : files) { if (file2.isDirectory()) { System.out.println("文件夹:" + file2.getAbsolutePath()); traverseFolder2(file2.getAbsolutePath()); } else { System.out.println("文件:" + file2.getAbsolutePath()); String name=file2.getName(); daoruFiles(file2.getAbsolutePath(), file2.getParentFile()+"\\"+name.replace(".txt", "")+"tongji"); } } } } else { System.out.println("文件不存在!"); } } }