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 }
  • 相关阅读:
    Time Zone 【模拟时区转换】(HDU暑假2018多校第一场)
    HDU 1281 棋盘游戏 【二分图最大匹配】
    Codeforces Round #527 (Div. 3) F. Tree with Maximum Cost 【DFS换根 || 树形dp】
    Codeforces Round #527 (Div. 3) D2. Great Vova Wall (Version 2) 【思维】
    Codeforces Round #527 (Div. 3) D1. Great Vova Wall (Version 1) 【思维】
    Codeforces Round #528 (Div. 2, based on Technocup 2019 Elimination Round 4) C. Connect Three 【模拟】
    Avito Cool Challenge 2018 E. Missing Numbers 【枚举】
    Avito Cool Challenge 2018 C. Colorful Bricks 【排列组合】
    005 如何分析问题框架
    004 如何定义和澄清问题
  • 原文地址:https://www.cnblogs.com/cxy0210/p/11795573.html
Copyright © 2011-2022 走看看