输入一段文章,输出最高频与次高频的单词(全部小写,逗号分隔)。文章中仅出现空格,逗号和句号这三种分隔符。
不考虑频率一致的情况。忽略大小写。
输入:I am a student.I come from XiDian,I love XiDian.
输出:i,xidian
开始的思路为根据句号切割字符串、然后在按逗号、空格切割字符串,但是后来发现这样进行很麻烦,发现根据正则表达式匹配字符串为单词,然后在将单词利用Map集合进行存储,key值存储单词,利用value值存储单词出现的次数,由于key值是唯一的所以没出现一次将所对应的value值加1.以上代码又测试用的所以没去掉。代码思路以及代码参考了 http://www.oschina.net/code/snippet_855019_15327#25177。
不考虑频率一致的情况。忽略大小写。
输入:I am a student.I come from XiDian,I love XiDian.
输出:i,xidian
正则:[a-zA-Z0-9\s]+ 正则表达式匹配英文、数字和空格
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class WordCount {
public static void main(String[] args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
System.out.println("请输入一串字符:");
String str = in.readLine();
String trim = str.trim();
System.out.println(trim);
if(trim != null && !"".equals(trim)){
Pattern expression = Pattern.compile("[a-zA-Z]+");// 定义正则表达式匹配单词
Matcher matcher = expression.matcher(trim);//
Map<String, Integer> map = new TreeMap<String, Integer>();
String word = "";
int times = 0;
//自是匹配单词,如果不是的话就不取单词
while (matcher.find()) {// 是否匹配单词
word = matcher.group();// 得到一个单词-树映射的键
if (map.containsKey(word)) {// 如果包含该键,单词出现过
times = map.get(word);// 得到单词出现的次数
map.put(word, times + 1);
} else {
map.put(word, 1);// 否则单词第一次出现,添加到映射中
}
}
String maxKey = "";
int maxValue = 0;
int secondMaxValue = 0;
String secondKey = "";
for(Map.Entry<String, Integer> entry:map.entrySet()){
String key = entry.getKey();
int value = entry.getValue();
if(value > maxValue){
maxValue = value;
maxKey = key;
}
if(value > secondMaxValue && value <maxValue){
secondMaxValue = value;
secondKey = key;
}
}
System.out.println("最大的出现次数和单词" + maxValue + "_"+maxKey);
System.out.println("次大的出现次数和单词" + secondKey + "_"+secondMaxValue);
/*
* 核心:如何按照TreeMap 的value排序而不是key排序.将Map.Entry放在集合里, 重写比较器,在用
* Collections.sort(list, comparator);进行 排序
*/
/* List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(map.entrySet());
* 重写比较器
* 取出单词个数(value)比较
Comparator<Map.Entry<String, Integer>> comparator = new Comparator<Map.Entry<String, Integer>>() {
public int compare(Map.Entry<String, Integer> left,
Map.Entry<String, Integer> right) {
return (left.getValue()).compareTo(right.getValue());
}
};
Collections.sort(list, comparator);// 排序
// 打印
int last = list.size() - 1;
for (int i = last; i >= 0; i--) {
String key = list.get(i).getKey();
Integer value = list.get(i).getValue();
System.out.println(key + " :" + value);
}*/
}
}
/**
* 匹配数字字母和逗号句号空格(出现一次或者多次)
* @param str
* @return
*/
public static boolean isMatching(String str){
Pattern p = Pattern.compile("^[0-9a-zA-Z,.。\\s]*$");
Matcher m = p.matcher(str);
if(!m.matches()){
return false;
}
return true;
}
}
开始的思路为根据句号切割字符串、然后在按逗号、空格切割字符串,但是后来发现这样进行很麻烦,发现根据正则表达式匹配字符串为单词,然后在将单词利用Map集合进行存储,key值存储单词,利用value值存储单词出现的次数,由于key值是唯一的所以没出现一次将所对应的value值加1.以上代码又测试用的所以没去掉。代码思路以及代码参考了 http://www.oschina.net/code/snippet_855019_15327#25177。