一、代码实现
import java.io.*;
import java.util.*;
/**
功能:统计文件中每个字符出现的次数
思路:
1.定义字符读取(缓冲)流
2.循环读取文件里的字符,用一个String类型变量接收(newValue)
3.把newValue变成字符数组 char[] ch = newValue.toCharArray();
4.遍历ch,将ch中所有的字符存入一个Map集合中(TreeSet),键对应字符,值对应字符出现的次数
5.遍历打印map集合中的键和值,也就是字符出现的次数
**/
public class Stat {
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
stat(new File("e:\\input.txt"));
long endTime = System.currentTimeMillis();
System.out.println("\n运行时间:" + (endTime - startTime) + "毫秒");
}
public static void stat(File file){
BufferedReader bfr = null; //定义字符读取(缓冲)流
try{
bfr = new BufferedReader(new FileReader(file)); //给该流赋值
String value = null; //定义一个临时接收文件中的字符串变量
String newValue = ""; //接收文件中所有字符串的变量
while((value = bfr.readLine()) != null){ //开始读取文件中的字符
newValue = newValue + value; //存入newValue变量中
}
char[] ch = newValue.toCharArray(); //把newValue变成字符数组
TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>(); //定义一个TreeMap,默认从小到大顺序,键对应字符,值对应字符出现的次数
for(int x = 0;x < ch.length; x++){ //遍历ch,将ch中所有的字符存入一个Map集合中(TreeSet),键对应字符,值对应字符出现的次数
char c = ch[x];
if(tm.containsKey(c)){ //如果TreeMap(tm)中有该键,则取出该键中的值,也就是出现的次数
int count = tm.get(c);
tm.put(c, count + 1); //把新值存入tm集合中,如果键相同的话, 新键会替换老键,值也随着变化了
}
else{
tm.put(c, 1); //如果没有出现该键就说明是第一次出现,存入1次
}
}
//下面的是取出TreeMap(tm)中的键和值
Set<Map.Entry<Character, Integer>> set = tm.entrySet();
Iterator<Map.Entry<Character, Integer>> iter = set.iterator();
while(iter.hasNext()){
Map.Entry<Character, Integer> map = iter.next();
char k = map.getKey();
int v = map.getValue();
System.out.print(k + "(" + v + "次) ");
}
}
catch(IOException e){
System.out.println("文件读取错误");
}
finally{
try{
if(bfr!=null)
bfr.close();
}
catch(IOException e){
System.out.println("文件关闭错误");
}
}
}
}
二、测试结果
1 在E:\input.txt中输入两行数据:
Hello World!
您好世界!
运行结果为:
(1次) !(1次) H(1次) W(1次) d(1次) e(1次) l(3次) o(2次) r(1次) 世(1次) 好(1次) 您(1次) 界(1次) !(1次) ,(1次)
运行时间:1毫秒
注:上面第1个没显示出来的字符是空格。
2 在E:\inut.txt中多放些数据,比如放了1.2M的数据,运行时间是3秒。
这里可以看出,这个算法仅仅是实现了最基本需求,当文件很大时,需要很长的时间才能得出结果。如果是在真实项目里,需要提高此算法的效率,或改用其它思路来实现。