词频统计程序无法进入for循环体。

FuuYY
  • 55

问题说明:
这是自己尝试写的字频统计的代码,但是调试时没有输出,于是在代码中间插入了很多输出语句,发现程序无法进入for循环体,程序中所有的for循环体都直接被跳过了。

代码如下:

import java.io.*;
import java.util.*;

public class Counter {
    public static String txt2String(File file){
        StringBuilder result = new StringBuilder();
        try{
            BufferedReader br = new BufferedReader(new FileReader(file));//构造一个BufferedReader类来读取文件
            String s = null;
            while((s = br.readLine())!=null){                            //使用readLine方法,一次读一行
                result.append(System.lineSeparator()+s);
            }
            br.close();    
        }catch(Exception e){
            e.printStackTrace();
        }
        return result.toString();
    }
    
    public static void count(String str) {
          String[] strarray = str.split("\b");
          ArrayList<String> list = new ArrayList<String>();
          ArrayList<Integer> num = new ArrayList<Integer>();
          int temp = 1;
          System.out.println("list和num初始化完成。");
          System.out.println("开始剔除重复并计数。");
          for(int i = 0; i<list.size(); i++) {
              System.out.println("进入循环体。");
              int flag = 0;
              for(int j = 0; j<i; j++) {
                  if(strarray[j].equals(strarray[i])) {
                      flag = flag+1;
                      for(int m =0; m<list.size(); m++) {
                          if(strarray[m].equals(strarray[j])) {
                              temp++;
                              num.add(j,temp);
                          }
                      }
                      System.out.println("遇到重复单词。");
                      break;
                      
                  }
                  else {
                      System.out.println("这次没遇到重复单词。");
                  }
              }
              if(flag==0) {
                  list.add(i,strarray[i]);
                  System.out.println("成功添加一个新单词。");
              }
          }
          System.out.println("准备输出最终统计结果。");
          for(int i =0; i<list.size(); i++) {
              System.out.print(list.get(i));
              System.out.print(":出现了");
              System.out.print(num.get(i));
              System.out.println("次");
          }
    }

    public static void main(String[] args) {
        File file = new File("D:\\java eclipse\\eclipse-workspace\\Counter\\src\\news.txt");
        String str = new String(txt2String(file));
        count(str);
    }
}

控制台输出结果如下:

clipboard.png

纠错尝试:
查了ArrayList遍历和add的用法,感觉应该没错。(但是我是新手 第一次用ArrayList也不是很确定,不清楚是不是和这个有关)
搜索了无法进入for循环的情况,没找到什么有价值的信息。

PS:
希望能有人帮忙解答我的问题或者可以提供字频统计程序的源码参考,谢谢!

回复
阅读 1.8k
2 个回答
✓ 已被采纳

后来自己又重新查了一下资料,重新写了一下。
用map来存储单词和频数显然更加合理一些,用Comparator来做升降序排列。
这是老师给的一道实验题,发一下题目吧,和我一样的初学者有兴趣也可以写着试一试。
题目如下:

clipboard.png

clipboard.png

我把后来写的代码重新发一下。

代码如下:

import java.io.*;
import java.io.FileReader;
import java.util.*;
import java.util.Map.Entry;

public class Counter {
    public static List<String> txt2String(File file) throws Exception{
        BufferedReader br = new BufferedReader(new FileReader("D:\\java eclipse\\eclipse-workspace\\Counter\\src\\news.txt"));    
        List<String> lists = new ArrayList<String>();  //存储过滤后单词的列表    
        String readLine = null;  
        while((readLine = br.readLine()) != null){    
            String[] wordsArr1 = readLine.split("[^a-zA-Z]");  //过滤出只含有字母的    
            for (String word : wordsArr1) {    
                if(word.length() != 0){  //去除长度为0的行    
                    lists.add(word);    
                }    
            }    
        }    
            
        br.close();    
        return lists;
    }
    
    public static void count(List<String> lists) {
         Map<String, Integer> wordsCount = new TreeMap<String,Integer>();  //存储单词计数信息,key值为单词,value为单词数         
         
            //单词的词频统计    
            for (String li : lists) {    
                if(wordsCount.get(li) != null){    
                    wordsCount.put(li,wordsCount.get(li) + 1);    
                }else{    
                    wordsCount.put(li,1);    
                }    
        
            }
            ArrayList<Map.Entry<String,Integer>> list = new ArrayList<Map.Entry<String,Integer>>(wordsCount.entrySet());
            Collections.sort(list,new Comparator<Map.Entry<String,Integer>>(){    
                @Override    
                public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {    
                    return o2.getValue() - o1.getValue();  //降序    
                    //return o1.getValue() - o2.getValue();    //升序
                }    
            });
            //for(Map.Entry<String,Integer> m:wordsCount.entrySet()){
            //    System.out.println(m.getKey()+" "+m.getValue());
            //    }  
            for(int i = 0; i<list.size(); i++){    
                System.out.println(list.get(i).getKey()+ ": " +list.get(i).getValue());    
            }  
    }

    public static void main(String[] args) throws Exception{
        File file = new File("D:\\java eclipse\\eclipse-workspace\\Counter\\src\\news.txt");
        List<String> lists = new ArrayList<String>(txt2String(file));
        count(lists);
    }
}

运行结果如下:

clipboard.png

如有错误,敬请指正。

代码中有很多问题,基本上思路就是错的。1,读文件有问题,txt2String中System.lineSeparator()应该加s后面。2,分割字符串有问题,count函数str.split("b");未考虑其它分隔符的情况,正确的做法是用正则表达式str.split("\s");。3,初始化后,list.size()=0,当然不会进入循环。

如果只想要代码的话看这里,java 字符串词频统计实例代码
下面代码是连接中的内容

import java.util.ArrayList; 
import java.util.Collections; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
 
public class WordsStatistics { 
 
    class Obj { 
        int count ; 
        Obj(int count){ 
            this.count = count; 
        } 
    } 
 
    public List<WordCount> statistics(String word) { 
        List<WordCount> rs = new ArrayList<WordCount>(); 
        Map <String,Obj> map = new HashMap<String,Obj>(); 
 
        if(word == null ) { 
            return null; 
        } 
        word = word.toLowerCase(); 
        word = word.replaceAll("'s", ""); 
        word = word.replaceAll(",", ""); 
        word = word.replaceAll("-", ""); 
        word = word.replaceAll("\\.", ""); 
        word = word.replaceAll("'", ""); 
        word = word.replaceAll(":", ""); 
        word = word.replaceAll("!", ""); 
        word = word.replaceAll("\n", ""); 
 
        String [] wordArray = word.split(" "); 
        for(String simpleWord : wordArray) { 
            simpleWord = simpleWord.trim();  
            if (simpleWord != null && !simpleWord.equalsIgnoreCase("")) { 
                Obj cnt = map.get(simpleWord); 
                if ( cnt!= null ) { 
                    cnt.count++; 
                }else { 
                    map.put(simpleWord, new Obj(1)); 
                } 
            } 
        } 
 
        for(String key : map.keySet()) { 
            WordCount wd = new WordCount(key,map.get(key).count); 
            rs.add(wd); 
        } 
 
        Collections.sort(rs, new java.util.Comparator<WordCount>(){ 
            @Override
            public int compare(WordCount o1, WordCount o2) { 
                int result = 0 ; 
                if (o1.getCount() > o2.getCount() ) { 
                    result = -1; 
                }else if (o1.getCount() < o2.getCount()) { 
                    result = 1; 
                }else { 
                    int strRs = o1.getWord().compareToIgnoreCase(o2.getWord()); 
                    if ( strRs > 0 ) { 
                        result = 1; 
                    }else { 
                        result = -1 ; 
                    } 
                } 
                return result; 
            } 
 
        }); 
        return rs; 
    } 
 
 
    public static void main(String args[]) { 
        String word = "Pinterest is might be aa ab aa ab marketer's dream  - ths site is largely used to curate products " ; 
        WordsStatistics s = new WordsStatistics(); 
        List<WordCount> rs = s.statistics(word); 
        for(WordCount word1 : rs) { 
            System.out.println(word1.getWord()+"*"+word1.getCount()); 
        } 
    } 
 
} 
宣传栏