读取一篇英文文章,输出其中出现单词的次数最多的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 tempMap=new HashMap();
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> list=new LinkedList>(tempMap.entrySet());
//重写比较器
Comparator> comparator=new Comparator>() {
@Override
public int compare(Entry o1,
Entry o2) {
return o1.getValue().compareTo(o2.getValue());
}
};
//找到最大的5个,找到就删掉.
for(int i=0;i<5;i++){
//Collections.max,找到集合中最大的.
Map.Entry 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 tempMap=new TreeMap();
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> list=new ArrayList>(tempMap.entrySet());
Comparator> comparator=new Comparator>() {
@Override
public int compare(Entry o1,
Entry 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看到的,正好自己也没什么事,对这个也感兴趣,就自己跑去写了下代码.该来改去的.汗.