使用文件读写操作统计哈利波特英文版中的字母,单词,并按要求输出

我们两清 提交于 2019-12-03 21:00:07

要求如下:

1.将哈利波特英文电子版导入,并统计每个英文字母出现概率(区分大小写),由大到小排序

2.统计该txt 文件中每个单词的个数,并按照要求输出频率最高的几个单词数目 和出现概率

 功能1:

输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列。

功能2:

指定目录,对目录下的每一个文件执行功能1 操作

功能3:

指定文件目录,但是会递归目录下的所有子目录,每个文件执行功能1的操作。

问题:

1.程序如何识别每一个单词: 当出现非字母符号时划分为一个单词,用正则表达式来分割句子, 形成单词;

1             //非单词用来分割单词
2             String [] words = str.split("[^(a-zA-Z)]+");

 

2.如何存储单词和后边的数据:使用Map 数组, key值设置为 String 存储单词 ,value 根据需要改变类型

1 //创建哈希表 记录数目
2             Map<String,Integer> map =new HashMap<String,Integer>();

 

主要思想:

读取文件内的数据,将数据转换为char类型,区分大小写统计字母个数,于此同时统计字母总个数。

1.使用BufferedReader 读取的缓存流进行读取,将数据添加到字符串缓冲区 StringBuffer 当中,将字符串缓冲区中的数据转换为char类型进行存储,进行一个循环遍历,用Character.isLetter() 方法判断是否是字母,进而用Character.isLowerCase()判断是否是小写字母,用数组存储每个字母的出现次数,数组下标  如果是小写字母,则数组下标为 该字符(a-'a')(使用ASCII码表) 下标为0-25的存储小写字母,0-26存储大写字母,大写字母下标表示方法: a-'A'+26 ;

重新定义一个double 数组,长度为52,按顺序存储每个单词出现的频率百分比。 创建一个map 数组,key 存储 英文字母, value 存储 频率百分比。 定义一个list集合,里面存储Map类型 ,调用 Collections.sort()方法 进行 排序 ,遍历List 集合输出 

key与value的 值。

 2.将录入的单词首先存到String数组当中,然后遍历String 数组,如果没有该单词的存储就创建一个map存储,如果已有该单词value+1,于此同时赋值number为单词总个数.

遍历完成,针对 map数组的value 值进行排序,最后按要求输出出现次数频率最高的几个单词,以及根据要求输出的出现概率。

功能1:

调用要求2的数据,自定义一个 hashtable的排序方法(哈哈,本人目前还没有搞明白。。。。),按照功能进行排序

功能2:

用file的isFile 判断是路径指向是否是文件,如果是文件则执行功能1,如果不是则将该目录下的文件存储到File 类型数组,进行遍历并执行功能1.

功能3;

与功能2类似,如果路径指向目录,则遍历目录,如果遇到目录则继续遍历,不是就执行功能1.

源码如下:

  1 package com.FileReaderWriter;
  2 
  3 
  4 import java.io.BufferedReader;
  5 import java.io.File;
  6 import java.io.FileNotFoundException;
  7 import java.io.FileReader;
  8 import java.io.IOException;
  9 import java.nio.charset.Charset;
 10 import java.util.ArrayList;
 11 import java.util.Collections;
 12 import java.util.Comparator;
 13 import java.util.HashMap;
 14 import java.util.Hashtable;
 15 import java.util.List;
 16 import java.util.Map;
 17 import java.util.Scanner;
 18 
 19 /** 
 20  *  信1805-2
 21  *  读取小说 并排序字母出现概率
 22  * @author cuixingyu
 23  *  按要求输出出现频率最高的单词和概率
 24  */
 25 public class FileReaderWriter {
 26     
 27     //查找单词并按要求输出
 28     public static void word(String c) throws Exception {
 29     
 30             File file =new File(c);
 31             //导入路径
 32             FileReader fr=new FileReader(file);
 33             //带缓冲的输出流
 34             BufferedReader br=new BufferedReader(fr);
 35             //构造一个没有字符的字符串缓冲区,初始容量为16个字符
 36             StringBuffer sb= new StringBuffer();
 37             String text=null;
 38             //将读入的一行信息存储到text 中
 39             while((text=br.readLine())!=null) {
 40                 //将读取出的字符text追加到StringBuffer 的 sb流中
 41                 sb.append(text);
 42             }
 43             //关闭读入流
 44             br.close(); 
 45             
 46             //将sb缓存流中的所有单词转换为String 类型 然后变为小写
 47             String str = sb.toString().toLowerCase();
 48             //非单词用来分割单词
 49             String [] words = str.split("[^(a-zA-Z)]+");
 50             //创建哈希表 记录数目
 51             Map<String,Integer> map =new HashMap<String,Integer>();
 52             // forreach 语句,均可转换为for循环语句     for(元素类型    元素变量 x:遍历对象obj)
 53             double number=0;
 54             double k=0;
 55             for(String word :words){  
 56                 if(map.get(word)==null){  // 若不存在说明是第一次,则加入到map,出现次数为1
 57                     map.put(word,1);
 58                     number++;
 59                     k++;
 60                 }else{
 61                     map.put(word,map.get(word)+1);  // 若存在,次数累加1
 62                     number++;
 63                 }
 64             }
 65             
 66             //排序
 67             //使用list集合 定义一个数组类型 list集合里放Map类型 每个Map的key 为String类型 对应的value为Integer 类型
 68             //map.entrySet()  返回此地图中包含的映射的Set视图。   ??
 69              List<Map.Entry<String ,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(map.entrySet()); 
 70             
 71              Comparator<Map.Entry<String,Integer>> comparator = new Comparator<Map.Entry<String, Integer>>() {
 72                  public int compare(Map.Entry<String, Integer> left, Map.Entry<String, Integer> right) 
 73                  {
 74                      return (left.getValue().compareTo(right.getValue()));
 75                   }
 76                 };
 77                 
 78                 //排序方法 默认为 升序
 79                 
 80                 
 81                 Collections.sort(list,comparator);
 82                 System.out.println("单词总个数:"+number);
 83                 System.out.println("不相同单词个数:"+k);
 84                 System.out.println("请输入要查询的位数N:");
 85                 Scanner sc=new Scanner(System.in);
 86                 int n=sc.nextInt();
 87                 for(int j=0;j<n;j++) {
 88                     double b=(list.get(list.size()-j-1).getValue()/number)*100;
 89                     System.out.println(list.get(list.size()-j-1).getKey() +":"+list.get(list.size()-j-1).getValue()+" "+String.format("%.2f", b)+"%");  //输出结果
 90                 }
 91                 
 92                 
 93                 //找寻文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列
 94                 Hashtable<String,Integer> hashtable=new Hashtable<String,Integer>();
 95                 
 96                 for(String word :words){  
 97                     // 若不存在说明是第一次,则加入到map,出现次数为1
 98                     if(hashtable.get(word)==null){  
 99                         hashtable.put(word,1);
100                     }else{
101                         // 若存在,次数累加1
102                         hashtable.put(word,hashtable.get(word)+1);  
103                     }
104                 }
105                 //把哈希表排序
106                 mapValueSort((Hashtable<String,Integer>)hashtable); //把哈希表排序
107     }
108     //自定义哈希排序 输出按照个数 字母表排序
109     private static void mapValueSort(Hashtable<String, Integer> hashtable) {
110         // TODO Auto-generated method stub
111            List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(hashtable.entrySet());//创建集合list,并规范集合为哈希表类型,并用hashtable.entrySet()初始化
112          //定义list排序函数 
113            list.sort(new Comparator<Map.Entry<String, Integer>>() 
114             {
115              public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2)
116              { 
117                 //比较两者之间字典序大小并其值赋给变量a
118                  int a=o1.getKey().compareTo(o2.getKey());
119                 //比较两者之间次数的大小
120                  if(o1.getValue() < o2.getValue())                    
121                  {
122                      return 1;                                        //若后者大返回1,比较器会将两者调换次序,此为降序
123                  }
124                 else if((o1.getValue() == o2.getValue())||((o1.getValue()==1)&&(o2.getValue()==1)))    //若次数相同比较字典序
125                 {
126                     if(a!=0&&a>0)                                    //字典序在前的在前面
127                      {
128                          return 1;
129                      }
130                 }
131                 return -1;
132                }
133             });
134             int k=0;
135             double sum=0;
136             for (Map.Entry<String, Integer> mapping :list) //遍历排序后的集合
137             {
138 
139                     sum+=mapping.getValue();
140             }
141       
142             System.out.println("功能1:输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列");
143             for (Map.Entry<String, Integer> mapping :list) //遍历排序后的集合
144             {
145                 System.out.println(mapping.getKey() + ":" + mapping.getValue());
146             }
147         
148     }
149     //查找字母并按要求输出。
150     public void  character(String c) throws Exception {
151         //导入路径
152         FileReader fr=new FileReader(c);
153         //带缓冲的输出流
154         BufferedReader br=new BufferedReader(fr);
155         //构造一个没有字符的字符串缓冲区,初始容量为16个字符
156         StringBuffer sb= new StringBuffer();
157         String text=null;
158         //将读入的一行信息存储到text 中
159         while((text=br.readLine())!=null) {
160             //将读取出的字符text追加到StringBuffer 的 sb流中
161             sb.append(text);
162         }
163         //关闭读入流
164         br.close(); 
165         
166         //将字符串转换为单个的字符
167         char[] str=sb.toString().toCharArray();
168         
169            //统计单词个数        
170            double number=0;
171            //计数数组
172            int []count=new int [52];
173           
174            for(int i=0;i<str.length;i++) {
175                //判断该字符是否时字母
176             if(Character.isLetter(str[i])) {
177                 //判断是否时小写字母
178                 if(Character.isLowerCase(str[i])) 
179                 {
180                     count[str[i]-'a']++;
181                     number++;
182                 }else {
183                     count[str[i]-'A'+26]++;
184                     number++;
185                    }
186             }
187           }
188            
189            //计算概率
190           double []s=new double [52] ; 
191           for(int k=0;k<52;k++) {
192               //化为百分比
193               s[k]=count[k]/number*100;
194            }
195           //定义哈希表
196           Map<String,Double> map =new HashMap<String,Double>();
197           
198            for(int i=0;i<s.length;i++) {
199                
200                //哈希表 前一个记录字母,后一个记录概率
201                if(i<26) {
202                    //小写字母统计
203                    char q=(char)(i+97);
204                    String key=String.valueOf(q);
205                map.put(key, s[i]);
206                }else {
207                    //大写字母统计
208                    char q=(char)(i+65-26);
209                    String key=String.valueOf(q);
210                map.put(key, s[i]);
211                }
212            }
213           
214       
215            //排序 默认为升序
216            
217            List<Map.Entry<String,Double>> list = new ArrayList<Map.Entry<String,Double>>(map.entrySet()); 
218             
219              Comparator<Map.Entry<String,Double>> comparator = new Comparator<Map.Entry<String,Double>>() {
220                  public int compare(Map.Entry<String,Double> left, Map.Entry<String,Double> right) 
221                  {
222                      return (left.getValue().compareTo(right.getValue()));
223                   }
224                 };
225                 
226             
227                 Collections.sort(list,comparator); 
228                
229                 for(int j=0;j<s.length;j++) {
230                     System.out.println(list.get(list.size()-j-1).getKey() +":"+String.format("%.2f", list.get(list.size()-j-1).getValue())+"%");  //输出结果
231                 }
232         
233     }
234     
235     //递归遍历目录下的所有子目录
236     @SuppressWarnings("null")
237     static void getPath(String a) throws Exception {
238         FileReaderWriter test1=null; 
239         File file = new File(a);
240          
241          File []array =file.listFiles();
242          for(int i=0;i<array.length;i++) {
243              //判断是否是目录
244             if(array[i].isDirectory()) {
245                  getPath(array[i].getPath());
246              }else {
247               word(array[i].getPath());     
248               }
249          }
250     }
251         
252 
253     public static void main(String[] args) throws Exception {
254         FileReaderWriter test= new FileReaderWriter();
255         String c="C://Users//cuixingyu//Desktop//Harry Potter and the Sorcerer's Stone.txt";
256         String b="D://cxy//454";
257         System.out.println("输出某个英文文本文件中 26 字母出现的频率,由高到低排列,并显示字母出现的百分比,精确到小数点后面两位:");
258         test.character(c);
259         
260         
261         
262         /*File file = new File(c);
263          if(file.isFile()) {
264          System.out.println("功能1:输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列");
265              test.word(c);
266          }
267           //指定文件目录,对目录下每一个文件执行  功能1的操作
268          else {
269          File []array =file.listFiles();
270          for(int i=0;i<array.length;i++) {
271          //判断是否是目录
272             if(!array[i].isDirectory()) {
273             System.out.println("功能1:输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列");
274                 test.word(array[i].getPath());
275             }
276          }
277         
278          }*/
279         
280         //递归遍历所给目录中的所有子目录,并进行功能1 操作
281         File file = new File(b);
282          if(file.isFile()) {
283              System.out.println("功能1:输出文件中所有不重复的单词,按照出现次数由多到少排列,出现次数同样多的,以字典序排列");
284              test.word(b);
285              }
286          else {
287              getPath(b);
288          }
289         }
290 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!