一个文本单词统计的案例

这次软件工程的一个个人项目是一个文本单词统计的小程序。

 

时间 8:00-9:00       9:00-10:45     11:00-15:00 次日8:00-9:30 10:00-11:30
动作   查阅资料 对1、2两部分代码的完成 对出现问题部分的调试  通过讨论完成调试   完善代码

因此它要实现的是读取文件,并能统计其中不同单词出现的次数,并按照由高到低的出现频数排序,并输出前10的单词及其出现的次数。

通过分析,则要实现以下2步:

1.对文本文件的读取,将一个一个的单词分离出来,并对单词进行统计。

在这里我们要用到文件的输入输出流(以下为部分主要代码):

 1 TreeMap<String, Integer> map = new TreeMap<String,Integer >();
 2         try 
 3         {
 4             fr=new BufferedReader(new FileReader(filename));
 5             System.out.println("======================");
 6             String len;
 7             while((len=fr.readLine())!=null)
 8             {
 9                 word=len.split(" |,");
10                 System.out.println(len);
11                 for( i=0;i<(word).length;i++)
12                 {
13                     String key=((word))[i].toLowerCase();
14                     if(((word))[i].length()>0)
15                     {
16                         if(map.get(key)==null)
17                         {    
18                             map.put(key, 1);cd++;
19                         }
20                         else
21                         {
22                             int value=map.get(key).intValue();
23                             value++;
24                             map.put(key, value);
25                         }
26                     }
27                 }
28             }
29             System.out.println("======================");
30         } 
31         catch (Exception e) 
32         {
33             System.out.println("出现异常!"+e.toString());
34              check=false;
35             // TODO: handle exception
36         }

在这里其实用到了java中的map集的结构。通过生成一个新的treemap对象,将单词及单词出现的次数分别对应到treemap<String,Integer>中,这样的结构方便使用(当然在排序是并未有很好的作用)。值得注意的是:map这样的泛型集有多种:Hashmap,Treemap等等。Treemap 的特点就是在输出时它是按照key值进行排序输出,及在这里它可以按照单词首字母排序输出。

2.对单词出现的次数进行排序。

if(check!=false)
    {
        try
        {
            System.out.println("单词的个数为(不重复的):"+cd);
        }catch(Exception e2)
        {
            System.out.println("异常处理2");
        }
        
        Iterator<String> it=  map.keySet().iterator();
        
        Integer tempcount;
        String tempname=null;
        Integer[] sortc=new Integer[cd];
        String[] sortn = new String[cd] ;
        i=0;
        while(it.hasNext()){
            
            String name = (String) it.next();
            Integer count=map.get(name);
            sortc[i]=count;
            sortn[i]=name;
            i++;
        }
        for(i=0;i<cd-1;i++)
        {
            for(j=0;j<cd-i-1;j++)
            {
                if((sortc)[j]<(sortc)[j+1])
                {
                    tempname=(sortn)[j];
                    tempcount=(sortc)[j];
                    (sortn)[j]=(sortn)[j+1];
                    (sortc)[j]=(sortc)[j+1];
                    ((sortn))[j+1]=tempname;
                    (sortc)[j+1]=tempcount;
                }
            }
        }
        System.out.println("输出出现次数最高的10个单词:");
        for(i=0;i<10;i++)
        {
            System.out.println((sortn)[i].toString()+"\t"+"       \t "+(sortc)[i]);
        }
     }
   }

在这里使用的是冒泡排序法,这样的效率会高一点。通过将treemap中的数据一一对应到两个数组中(注意:前面要统计好数组的长度,这样才能很好地定义数组)。

现在将完整的代码贴上:

  1 import java.io.*;
  2 import java.io.FileReader;
  3 import java.util.*;
  4 public class test1 {
  5     public static void main(String[] args) {
  6         System.out.println("请输入文件完整路径及名称");
  7         Scanner in = new Scanner(System.in);
  8         String filename=in.next();
  9         System.out.println(filename);
 10         BufferedReader fr=null;
 11         String[] word = null;
 12         int i = 0,j;
 13         int cd=0;
 14         boolean check=true;
 15         TreeMap<String, Integer> map = new TreeMap<String,Integer >();
 16         try 
 17         {
 18             fr=new BufferedReader(new FileReader(filename));
 19             System.out.println("======================");
 20             String len;
 21             while((len=fr.readLine())!=null)
 22             {
 23                 word=len.split(" |,");
 24                 System.out.println(len);
 25                 for( i=0;i<(word).length;i++)
 26                 {
 27                     String key=((word))[i].toLowerCase();
 28                     if(((word))[i].length()>0)
 29                     {
 30                         if(map.get(key)==null)
 31                         {    
 32                             map.put(key, 1);cd++;
 33                         }
 34                         else
 35                         {
 36                             int value=map.get(key).intValue();
 37                             value++;
 38                             map.put(key, value);
 39                         }
 40                     }
 41                 }
 42             }
 43             System.out.println("======================");
 44         } 
 45         catch (Exception e) 
 46         {
 47             System.out.println("出现异常!"+e.toString());
 48              check=false;
 49             // TODO: handle exception
 50         }
 51         /*for(i=0;i<word.length;i++)
 52         {
 53             if(word[i].contains(","))
 54             {
 55                 pureword=word[i].split(",");
 56             }
 57         }*/
 58     if(check!=false)
 59     {
 60         try
 61         {
 62             System.out.println("单词的个数为(不重复的):"+cd);
 63         }catch(Exception e2)
 64         {
 65             System.out.println("异常处理2");
 66         }
 67         
 68         Iterator<String> it=  map.keySet().iterator();
 69         
 70         Integer tempcount;
 71         String tempname=null;
 72         Integer[] sortc=new Integer[cd];
 73         String[] sortn = new String[cd] ;
 74         i=0;
 75         while(it.hasNext()){
 76             
 77             String name = (String) it.next();
 78             Integer count=map.get(name);
 79             sortc[i]=count;
 80             sortn[i]=name;
 81             i++;
 82         }
 83         for(i=0;i<cd-1;i++)
 84         {
 85             for(j=0;j<cd-i-1;j++)
 86             {
 87                 if((sortc)[j]<(sortc)[j+1])
 88                 {
 89                     tempname=(sortn)[j];
 90                     tempcount=(sortc)[j];
 91                     (sortn)[j]=(sortn)[j+1];
 92                     (sortc)[j]=(sortc)[j+1];
 93                     ((sortn))[j+1]=tempname;
 94                     (sortc)[j+1]=tempcount;
 95                 }
 96             }
 97         }
 98         System.out.println("输出出现次数最高的10个单词:");
 99         for(i=0;i<10;i++)
100         {
101             System.out.println((sortn)[i].toString()+"\t"+"       \t "+(sortc)[i]);
102         }
103      }
104    }
105 }

最后总结本次的个人项目:
在周四得知题目后,大致的将思路及方法理了一次。在有方法的前提下预估了本次实验完成时间为0.5人日,即4-6个小时的时间。但周六实际操作中也遇到问题,在解决问题上花费的时间很多,到周日上午才基本完成。在单词出现次数的统计这一块顺利完成,而排序是一个卡壳的地方。在想好用数组将treemap中的数据“导出”后,便确定了用冒泡排序法来进行排序。但问题恰恰出现在“导出”上。其实这里的“导出”就是将treemap中的<String,Integer>两种数据类型放置到String[]、int[]两个数组中。但出现nullpointerException的异常(空指针异常)就是在数组的初始化上出现了问题,因为我直接是这样定义的:String[] sortn=null; int[] sortc=null。其实应当要赋给一个确定的长度值。int[] sortc=new int[20];这样的才正确。为了不浪费空间及提高效率,我在单词统计之前就将不重复单词个数cd统计出来,这样就可以不浪费数组空间并能提高效率了。

 不过程序还存在明显的缺陷,即单词的判断上会出现差错(当符号与单词紧邻时无法正确的“剥离”出单词来)。

因此程序需要不断的检查,使其变得更好,正确完整的预计时间是很好解决问题的一个方法。

posted on 2014-02-26 17:51  FakerWang  阅读(1546)  评论(4编辑  收藏  举报

导航