统计指定字符串中出现次数最多的前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<String> list = Arrays.asList(str.split(""));
//		HashMap<String, Long> map= Arrays.stream(str.split("")).sorted()
               .collect(Collectors.groupingBy(Function.identity(),Collectors.counting()));
//               .collect(Collectors.groupingBy(Function.identity(),HashMap::new,Collectors.counting()))
//               ;
//		HashMap<String, Long> map = Arrays.stream(str.split("")).sorted().collect(Collectors.groupingBy(Function.identity(),HashMap::new,Collectors.counting()));
//		System.out.println(map);
//		Map<String, Long> 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<String, Long> map1 = new LinkedHashMap<String, Long>();
//		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<Map.Entry<String ,Integer>> getMaxMap(String str, Integer num) {
		String max_str = "";
		//取出前num个出现次数最多的字符,字符和出现次数放入map中
		Map<String, Integer> map = new HashMap<String, Integer>();
		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<Map.Entry<String ,Integer>> list = new ArrayList<Map.Entry<String ,Integer>>();
		Iterator<Map.Entry<String ,Integer>> iterator = map.entrySet().iterator();
		while(iterator.hasNext()) {
			list.add(iterator.next());
		}
        Collections.sort(list,new Comparator<Map.Entry<String ,Integer>>() {
            //升序排序
            public int compare(Entry<String ,Integer> o1,
                    Entry<String ,Integer> o2) {
                return o2.getValue().compareTo(o1.getValue());
            }
        });
		return list;
	}
	/**
	 * 功能实现
	 * @param str
	 * @param num
	 * @return
	 */
	public static Map<String, Integer> getMaxMap1(String str, Integer num) {
		String max_str = "";
		//取出前num个出现次数最多的字符,字符和出现次数放入map中
		Map<String, Integer> map = new LinkedHashMap<String, Integer>();
		//如果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<String, Long> getMaxMap2(String str, Integer num) {
		Map<String, Long> map1 = new LinkedHashMap<String, Long>();
		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}

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值