软件工程实践之词频统计

GitHub仓库地址: https://github.com/softwarehsc/java1

PSP表格:

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
合计   540  
· Test Repor · 测试报告 60 40
· Test · 测试(自我测试,修改代码,提交修改) 60 240
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 10 10
· Estimate · 估计这个任务需要多少时间 20 60
· Design Spec · 生成设计文档 30 30
· Design Review · 设计复审 30 10
· Design · 具体设计 60 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 20 15
· Coding · 具体编码 120 380
· Code Review · 代码复审 60 30
· Analysis · 需求分析 (包括学习新技术) 60 60
Reporting 报告 80 60
Planning 计划 60 60
Development 开发 480 795

需求分析
  1. 统计文件的字符数:

    • 只需要统计Ascii码,汉字不需考虑
    • 空格,水平制表符,换行符,均算字符
  2. 统计文件的单词总数,单词:至少以4个英文字母开头,跟上字母数字符号,单词以分隔符分割,不区分大小写。

    统计文件的有效行数:任何包含非空白字符的行,都需要统计。
    • 英文字母: A-Z,a-z
    • 字母数字符号:A-Z, a-z,0-9
    • 分割符:空格,非字母数字符号
    • 例:file123是一个单词, 123file不是一个单词。file,File和FILE是同一个单词
  3. 统计文件中各单词的出现次数,最终只输出频率最高的10个。频率相同的单词,优先输出字典序靠前的单词。
  4. 按照字典序输出到文件result.txt:例如,windows95,windows98和windows2000同时出现时,则先输出windows2000

    • 输出的单词统一为小写格式
  5. 输出的格式为

characters: number
words: number
lines: number <word1>: number <word2>: number
实现过程
在eclipse建立文件main.java包含文件的读入和主方法,调用lib.java中Print类的求characters、words、lines等的方法实现需求。
在WordCount类中首先通利用BufferedReader类通过从字符输入流中读取文本。将所有字母单词转换为小写形式,再次读取文档,通过正则表达式
过滤掉标点符号分离出单词存储在lists列表中(List<String> lists = new ArrayList<String>(); )。最后通过wordsCount存储单词计数信息(Map<String, Integer> wordsCount = new TreeMap<String,Integer>();)
代码说明
主方法类用于读取文本文件统计字符个数 并调用Prinit类中的函数输出相应words、lines等参数的值:
 1 public class WordCount {  
 2  
 3     public static void main(String[] args) throws Exception { 
 4         Scanner scanner=new Scanner(System.in);
 5         String pathname=scanner.nextLine();
 6         //将文本单词转化为小写
 7         Reader myReader = new FileReader(pathname);
 8         Reader myBufferedReader = new BufferedReader(myReader);
 9         CharArrayWriter  tempStream = new CharArrayWriter();  
10         int i = -1;
11         int k1=0;
12          do {
13              k1++;
14         if(i!=-1) 
15         tempStream.write(i);
16         i = myBufferedReader.read();
17         if(i >= 65 && i <= 90){
18         i += 32;
19         }
20         }while(i != -1);
21         myBufferedReader.close();
22         Writer myWriter = new FileWriter(pathname);
23         tempStream.writeTo(myWriter);
24         tempStream.flush();
25         tempStream.close();
26         myWriter.close();
27         ///再次读取文档
28     BufferedReader br = new BufferedReader(new FileReader(pathname));  
29         
30         List<String> lists = new ArrayList<String>();  //存储过滤后单词的列表  
31         String read= null;
32         while((read = br.readLine()) != null){  
33             String[] wordsArr1 = read.split("[^a-zA-Z]");  //过滤出只含有字母的  
34             for (String word : wordsArr1) {  
35                 if(word.length() != 0){  //去除长度为0的行  
36                     lists.add(word);  
37                 }  
38             }  
39         }  
40           
41         br.close();  
42           
43         Map<String, Integer> wordsCount = new TreeMap<String,Integer>();  //存储单词计数信息,key值为单词,value为单词数       
44         for (String li : lists) {  
45             if(wordsCount.get(li) != null){  
46                 wordsCount.put(li,wordsCount.get(li) + 1);  
47             }else{  
48                 wordsCount.put(li,1);  
49             }  
50   
51         }  
52         System.out.println("Characters: "+k1);
53         Print printwords=new Print();
54         printwords.printWords(wordsCount);
55         Print printline=new Print();
56         printline.printline(pathname);
57         Print printWordsFrequence=new Print();
58         printWordsFrequence.printWordFrequence(wordsCount);
59              }  
60 }
61  

1、printWords(Map<String,Integer> oldmap)函数用于输出文本单词总数:

 1  public static void printWords(Map<String,Integer> oldmap){  
 2          
 3             ArrayList<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(oldmap.entrySet());  
 4               
 5             Collections.sort(list,new Comparator<Map.Entry<String,Integer>>(){    
 6                 public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {  
 7                     return o2.getValue() - o1.getValue();  //降序  
 8                 }  
 9             }); 
10             
11             int sum=0;
12             for(int i = 0; i<list.size(); i++){  
13              sum+=list.get(i).getValue();  
14             }  
15             System.out.println("words: "+sum);    
16         }  
2、printline(String pathname)函数用于输出文本行数:
 1 public static void printline(String pathname)
 2     {
 3         try
 4         {
 5       BufferedReader br = new BufferedReader(new FileReader(pathname));  
 6       int count=0;
 7       while (br.ready()) { 
 8           br.readLine(); 
 9           count ++;
10       }
11       System.out.println("lilnes: "+count);
12          }
13         catch(IOException e) { 
14                 e.printStackTrace(); 
15             } 
16 }
3、 printWordFrequence(Map<String,Integer> oldmap)函数用于输出排名前十且以四个英文字母开头的单词的频率
 1  public static void printWordFrequence(Map<String,Integer> oldmap){  
 2          
 3             ArrayList<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(oldmap.entrySet());  
 4               
 5             Collections.sort(list,new Comparator<Map.Entry<String,Integer>>(){    
 6                 public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {  
 7                     return o2.getValue() - o1.getValue();  //降序  
 8                 }  
 9             }); 
10             int k=0;
11             for(int i = 0; i<list.size(); i++){ 
12                 if(k>10)break;
13                 if(list.get(i).getKey().length()>3)
14                 {
15                 System.out.println(list.get(i).getKey()+ ": " +list.get(i).getValue());  
16                 k++;
17             }    
18        
19             }
20         } 
 
 
 


 

 

 

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/heshoucheng/p/9610814.html