zoukankan      html  css  js  c++  java
  • 使用文件读写操作统计哈利波特英文版中的字母,单词,并按要求输出

    要求如下:

    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 }
  • 相关阅读:
    网络编程笔记--socket可读可写条件
    redis内核了解
    TIPI 阅读笔记 ----cgi 和 fastcgi
    csv 导 mysql
    Linux IO模式及 select、poll、epoll详解(转载)
    nginx 配置location php 不被解析解决办法
    汇编实验九
    汇编实验四
    实验三
    汇编 实验二
  • 原文地址:https://www.cnblogs.com/cxy0210/p/11795573.html
Copyright © 2011-2022 走看看