【大数据基础】统计某目录下的所有文本文件的单词出现频率

思路

  • 1.设置一个全局表来存放每一个出现过的单词和它的出现次数
  • 2.遍历所有文件,根据文件类型来判断是不是我们想要读取的文件
  • 3.读取文件内容
  • 4.把文件内容分割成一个个单词,并将文件中出现的单词,以及出现的次数存到全局表中
  • 5.根据出现次数从大到小排序数据
  • 6.打印出结果

实现

1.设置一个全局表来存放每一个出现过的单词和它的出现次数

这里用TreeMap方便我们排序

private static Map<String, Integer> table=new TreeMap<String, Integer>();

2.遍历所有文件,根据文件类型来判断是不是我们想要读取的文件

通过递归遍历目录下的所有文件,我们只读取c,cpp,java为后缀的文件。

    private static void statisticDir(File dir) {
        if(dir.isFile()) {
            return;
        }
        File[] fs=dir.listFiles();
        if(fs==null) {
            return;
        }
        for (File f:fs)
        {
            if (f.isFile())
            {
                String full=f.getAbsolutePath();
                if(full.endsWith(".c")||full.endsWith(".cpp")||full.endsWith(".java")) {
                    statisticFile(full);
                }
            }
            else{
                System.out.println("扫描:"+f.getAbsolutePath());//想快点可以把这行注释掉
                statisticDir(f);
            }

        }

    }

3.读取文件内容

    private static StringBuilder readFile(String file) {
        BufferedReader bufferedReader=null;
        StringBuilder stringBuilder=new StringBuilder();
        try {
            bufferedReader=new BufferedReader(new FileReader(file));
            String line=null;
            while ((line=bufferedReader.readLine())!=null) {
                
                stringBuilder.append(line+"\n");
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally {
            if(bufferedReader!=null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
        return stringBuilder;
    }

4.把文件内容分割成一个个单词,并将文件中出现的单词,以及出现的次数存到全局表中

这里将忽略单个字母的单词,支持大驼峰和小驼峰命名的单词组合拆分,例如:void setName(name);或者void SetName(Name);将被分解成4个单词。

    private static void statisticWordsBySentence(String sentence){
        int start=0;
        int end=0;
        String word=null;
        boolean scan=false;
        
        int len=sentence.length();
        State state=State.Other;
        for(int i=0;i<len;i++) {
            char ch=sentence.charAt(i);
            
            //小写字母
            if(Character.isLowerCase(ch)) {
                if(!scan){
                    start=i;
                    scan=true;
                }
                //根据前一个状态判断
                if(state==State.Other){
                    state=State.LowerCase;
                    scan=true;
                }
                else if(state==State.LowerCase||state==State.UpperCase){
                    if(i==len-1){
                        end=len;
                        if(end-start==1) {
                            //不要一个字母的单词
                            scan=false;
                            continue;
                        }
                        word=sentence.substring(start, end);
                        if(!sensitive){
                            word=word.toLowerCase();
                        }
                        if(table.containsKey(word)) {
                            int newVal=table.get(word)+1;
                            table.put(word, newVal);
                        }
                        else {
                            table.put(word, 1);
                        }
                    }
                }
                
            }
            //大写字母
            else if(Character.isUpperCase(ch)) {
                if(!scan){
                    start=i;
                    scan=true;
                    state=State.UpperCase;
                    continue;
                }
                if(state==State.LowerCase||state==State.UpperCase||state==State.Other){
                    end=(i==len-1)?len:i;
                    if(end-start==1) {
                        //不要一个字母的单词
                        scan=false;
                        continue;
                    }
                    word=sentence.substring(start, end);
                    if(!sensitive){
                        word=word.toLowerCase();
                    }
                    if(table.containsKey(word)) {
                        int newVal=table.get(word)+1;
                        table.put(word, newVal);
                    }
                    else {
                        table.put(word, 1);
                    }
                    state=State.UpperCase;
                    scan=true;
                    start=i;
                }
                
                
            }
            //其他
            else{
                if(!scan){
                    scan=false;
                    continue;
                }
                if(state!=State.Other){
                    end=(i==len-1)?len:i;
                    if(end-start==1) {
                        //不要一个字母的单词
                        scan=false;
                        continue;
                    }
                    word=sentence.substring(start, end);
                    if(!sensitive){
                        word=word.toLowerCase();
                    }
                    if(table.containsKey(word)) {
                        int newVal=table.get(word)+1;
                        table.put(word, newVal);
                    }
                    else {
                        table.put(word, 1);
                    }
                    state=State.Other;
                    scan=false;
                }
            }
            
        }
    }

5.根据出现次数从大到小排序数据

    private static List<Map.Entry<String, Integer>> sortData() {
        List<Map.Entry<String, Integer>> entryArrayList = new ArrayList<>(table.entrySet());
        Collections.sort(entryArrayList, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> v1, Map.Entry<String, Integer> v2) {
                // TODO Auto-generated method stub
                return v2.getValue()-v1.getValue();
            }
        });
        
        return entryArrayList;
    }

6.打印出结果

拼成Markdown的表格,使打印更加直观。在这里输出前100的排名,读者可自行调整

        System.out.println("| 排名 | 单词 | 出现频率 |");
        System.out.println("| ------------- |:-------------:| --------:|");
        for(int i=0;i<100;i++) {
            Map.Entry<String, Integer> entry=list.get(i);
            System.out.println("| "+(i+1)+" | "+entry.getKey()+" | "+entry.getValue()+" |");
        }

结果

在测试的时候,在大小写敏感模式下,统计某Java源码目录的结果,得到的结果如下:

排名单词出现频率
1the311620
2if160965
3int147354
4to124752
5ud122707
6return120929
7is103377
8of97253
9public82258
10code80901
11get80374
12in78338
13this72584
14for66639
15void66632
16const65662
17String61459
18and60536
19static58577
20be52238
21new52176
22value50750
23set48107
24define46341
25or44280
26final44272
27The43007
28null40870
29param39200
30ua35429
31Exception35177
32not33046
33that32959
34with31674
35char31605
36private30663
37name30092
38by28578
39else28552
40on27356
41data27117
42link26914
43type26831
44length26330
45an25982
46License25953
47class25941
48android24778
49udc24752
50Code24273
51This24032
52ude23355
53key22997
54from22842
55are22709
56Object22363
57result22353
58Unicode22143
59import22070
60as21689
61it21530
62td21388
63size21351
64Array20837
65status20546
66file20100
67case20058
68udd19954
69Type19706
70index19660
71View19528
72use19258
73include18985
74Name18622
75object18118
76start18109
77boolean17693
78Value17223
79will16990
80out16947
81error16763
82Set16560
83may16362
84To16344
85string16319
86err16081
87true15680
88throws15655
89endif15619
90unsigned15532
91long15313
92udf15279
93at15106
94ctx14984
95State14939
96Info14749
97If14680
98block14453
99false14434
100used14247

完整源码

https://github.com/luoyesiqiu/StatisticWords

转载于:https://www.cnblogs.com/luoyesiqiu/p/9412729.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值