今天面试碰到这个题,回来做一下。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* 从给定的字符串里统计出前10个出现次数最多的字符,并按出现次数从大到小排列
*
*/
public class StringStatistics {
public static void main(String[] args) {
String str = "anananklsnoijek nkn;ksmksjidnv mske;nfkla njbnjslnfjshaufjn salnfaw;mgkna;";
// String str = "aabbbccc";
System.out.println(getMaxMap(str, 10));
System.out.println(getMaxMap1(str, 10));
System.out.println(getMaxMap2(str, 10));
//字符串转为list
// List list = Arrays.asList(str.split(""));
// HashMap map= Arrays.stream(str.split("")).sorted()
//// .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
// .collect(Collectors.groupingBy(Function.identity(),HashMap::new,Collectors.counting()))
// ;
// HashMap map = Arrays.stream(str.split("")).sorted().collect(Collectors.groupingBy(Function.identity(),HashMap::new,Collectors.counting()));
// System.out.println(map);
// Map sortedMap2 = new LinkedHashMap<>();
// map.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(10).forEachOrdered(x -> sortedMap2.put(x.getKey(), x.getValue()));
// System.out.println(sortedMap2);
// Map map1 = new LinkedHashMap();
// Arrays.stream(str.split("")).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
// .entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(10)
// .forEachOrdered(x -> map1.put(x.getKey(), x.getValue()));
// System.out.println(map1);
}
/**
* 功能实现
* @param str
* @param num
* @return
*/
public static List> getMaxMap(String str, Integer num) {
String max_str = "";
//取出前num个出现次数最多的字符,字符和出现次数放入map中
Map map = new HashMap();
while (num > 0 && map.size() < num) {
str = str.replaceAll(max_str, "");
String newstr = str;
int max_length = 0;
max_str = "";
while (newstr.length() > 0) {
String first = newstr.substring(0, 1);
int length = newstr.length();
newstr = newstr.replaceAll(first, "");
if (max_length < length - newstr.length()) {
max_length = length - newstr.length();
max_str = first;
}
}
map.put(max_str, max_length);
}
//对map进行排序,得到结果list
List> list = new ArrayList>();
Iterator> iterator = map.entrySet().iterator();
while(iterator.hasNext()) {
list.add(iterator.next());
}
Collections.sort(list,new Comparator>() {
//升序排序
public int compare(Entry o1,
Entry o2) {
return o2.getValue().compareTo(o1.getValue());
}
});
return list;
}
/**
* 功能实现
* @param str
* @param num
* @return
*/
public static Map getMaxMap1(String str, Integer num) {
String max_str = "";
//取出前num个出现次数最多的字符,字符和出现次数放入map中
Map map = new LinkedHashMap();
//如果list中元素个数未达到,就继续往list放值
while (num > 0 && map.size() < num) {
str = str.replaceAll(max_str, "");
String newstr = str;
int max_length = 0;
max_str = "";
//取出newstr中出现次数最大的字符max_str和出现次数max_length,记录进map和list中
while (newstr.length() > 0) {
String first = newstr.substring(0, 1);
int length = newstr.length();
newstr = newstr.replaceAll(first, "");
if (max_length < length - newstr.length()) {
max_length = length - newstr.length();
max_str = first;
}
}
map.put(max_str, max_length);
}
return map;
}
/**
* 用jdk8实现
* @param str
* @param num
* @return
*/
public static Map getMaxMap2(String str, Integer num) {
Map map1 = new LinkedHashMap();
Arrays.stream(str.split("")).collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet().stream().sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(num)
.forEachOrdered(x -> map1.put(x.getKey(), x.getValue()));
return map1;
}
}
getMaxMap():第一版实现,先取出结果,放到map中,再对map按value进行排序。
getMaxMap1():第二版在前面的基础上,进行优化:其实在把结果放入map中时,相当于已经排了序,就不用再对map进行排序了。
getMaxMap2():第三版优化,用jdk8实现。
有一点值得留意:在main方法里同时调用这3个方法,得到的结果里,次数相同的字符排序顺序显示是不同的:
[n=14, a=8, k=8, s=7, j=6, =4, f=4, ;=4, l=4, m=3]
{n=14, a=8, k=8, s=7, j=6, l=4, =4, ;=4, f=4, m=3}
{n=14, a=8, k=8, s=7, j=6, =4, f=4, l=4, ;=4, m=3}
具体原因待解。如有更好的实现方式,欢迎指正