读取一篇英文文章,输出其中出现单词的次数最多的5个,写java函数

读取一篇英文文章,输出其中出现单词的次数最多的5个,写java函数.


这个应该是效率很高的一个.

package org.credo.txt;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RunTxt {

	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		System.out.println("开始读取文件.");
		//读取
		File file=new File("D:\\test.txt");
		//FileReader 用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream
		FileReader fileReader=new FileReader(file); 
		//从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。
		BufferedReader reader=new BufferedReader(fileReader);  
		StringBuilder builder=new StringBuilder();
		String line="";
		//如果读取到的下行数据不是null就继续循环.
		while ((line=reader.readLine())!=null) {
			//得到txt的所有字符.
			builder.append(line);
		}
		//关闭该流并释放与之关联的所有资源。
		reader.close();	
		
		//正则表达式匹配计算
		Pattern pattern=Pattern.compile("[a-zA-Z]+");
		String allStr=builder.toString();
		//创建匹配给定输入与此模式的匹配器。
		Matcher matcher=pattern.matcher(allStr);
		//因为不再是排序,所以用查询性能更好的HashMap
		Map<String, Integer> tempMap=new HashMap<String, Integer>();
		String word="";
		int times=0;
		int ii=0;
		//Matcher的find方法,找到匹配正则的下个字符.找到返回true.
		while (matcher.find()) {
			//返回由以前匹配操作所匹配的输入子序列。
			word=matcher.group();
			System.out.println("word:"+word);
			ii++;
			//Map的key包含这个单词就+1.否则为1.
			if(tempMap.containsKey(word)){
				times=tempMap.get(word);
				tempMap.put(word, times+1);
			}else{
				tempMap.put(word, 1);
			}
		}
		System.out.println("i:"+ii);
		
		//考虑到LinkedList做删除动作性能更好.所以采用LinkedList.而不是查询性能更好的ArrayList.
		List<Map.Entry<String, Integer>> list=new LinkedList<Map.Entry<String, Integer>>(tempMap.entrySet());
		//重写比较器
		Comparator<Map.Entry<String, Integer>> comparator=new Comparator<Map.Entry<String, Integer>>() {
			@Override
			public int compare(Entry<String, Integer> o1,
					Entry<String, Integer> o2) {
				return o1.getValue().compareTo(o2.getValue());
			}
		};
		//找到最大的5个,找到就删掉.
		for(int i=0;i<5;i++){
			//Collections.max,找到集合中最大的.
			Map.Entry<String, Integer> entry=Collections.max(list,comparator);
			String key=entry.getKey();
			Integer value=entry.getValue();
			list.remove(entry);
			System.out.println("key:"+key+".value:"+value+".被删除的entry:"+entry);
		}
		
		
	}

}

这个是被大家说的效率低的一个,

package org.credo.txt;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ComputeTxt {
	/**
	 * @throws Exception 
	 * 
	 */
	public static void main(String[] args) throws Exception{
		System.out.println("开始读取文件.");
		//读取
		File file=new File("D:\\test.txt");
		FileReader fileReader=new FileReader(file); 		//FileReader 用于读取字符流。要读取原始字节流,请考虑使用 FileInputStream
		BufferedReader reader=new BufferedReader(fileReader); //从字符输入流中读取文本,缓冲各个字符,从而实现字符、数组和行的高效读取。 
		StringBuilder builder=new StringBuilder();
		String line="";
		while ((line=reader.readLine())!=null) {
			builder.append(line);
		}
		reader.close();	//关闭该流并释放与之关联的所有资源。
		
		//正则表达式匹配计算,使用Map接口排序性能最好的TreeMap类.
		Pattern pattern=Pattern.compile("[a-zA-Z]+");
		String allWord=builder.toString();
		Matcher matcher=pattern.matcher(allWord);
		Map<String, Integer> tempMap=new TreeMap<String, Integer>();
		String word="";
		int count=0;
		int ii=0;
		while (matcher.find()) {
			word=matcher.group();
			System.out.println("word:"+word);
			ii++;
			if(tempMap.containsKey(word)){
				count=tempMap.get(word);
				tempMap.put(word, count+1);
			}else{
				tempMap.put(word, 1);
			}
		}
		System.out.println("i:"+ii);
		List<Map.Entry<String, Integer>> list=new ArrayList<Map.Entry<String, Integer>>(tempMap.entrySet());
		Comparator<Map.Entry<String, Integer>> comparator=new Comparator<Map.Entry<String, Integer>>() {
			@Override
			public int compare(Entry<String, Integer> o1,
					Entry<String, Integer> o2) {
				return o1.getValue().compareTo(o2.getValue());
			}
		};
		Collections.sort(list,comparator);
		
		int last = list.size() - 1;
		for (int i = last; i > last - 5; i--) {
			String key = list.get(i).getKey();
			Integer value = list.get(i).getValue();
			System.out.println(key + " :" + value);
		}
		System.out.println("Over");
	}
}

问题是如果数据量非常大的话,就是文本内容有一本新华字典,这方法应该也不行,内存直接溢出.有什么好办法没?


题目是在@abian的原发http://www.oschina.net/code/snippet_855019_15327看到的,正好自己也没什么事,对这个也感兴趣,就自己跑去写了下代码.该来改去的.汗.

你可能感兴趣的:(集合,IO,面试题,正则)