统计指定字符串中出现次数最多的前10个字符及每个字符出现的次数,结果按次数从大到小排列

今天面试碰到这个题,回来做一下。

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}

具体原因待解。如有更好的实现方式,欢迎指正

你可能感兴趣的:(java基础)