题目
哈夫曼编码是一种编码方式,是可变字长编码的一种,由Huffman 于1952 年提出。该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫Huffman 编码。简单地来说,就是出现概率高的字符使用较短的编码,反之出现概率低的则使用较长的编码,这便使编码之后的字符串的平均期望长度降低,从而达到无损压缩数据的目的。
现在请你模拟这样的原则对给定的一个字符串进行字母统计。
输入格式:只有一行,是一个字符串,由长度不超过255个字符的小写英文字母组成。
输出格式:有若干行,每行由两部分组成:一个字母和该字母出现的频率,中间用一个空格分隔,并按频率高低排列,频率相同时则按字母的ASCII码的先后顺序排列。
样例:
输入
soon
输出
o 2
n 1
s 1
解题思路
作为一只妥妥的小学渣,一开始看到这道题,我想到的是用字符串的正则匹配针对每个匹配到的字母,再放进Map中。Map的键正是字母,值就是出现的次数。但是这样做下去,我就发现了自己有多么愚蠢。首先用了正则表达式对于每一个输入放字符都要声明Matcher的对象,增加了空间和时间。第二用Map虽然表面上非常方便第记录了字母和它出现的次数,但是输出格式可愁坏我了。输出时,需要按出现频率高到低,频率相同的按字母的ASCLL码输出。我当时发觉用了Map就是把自己给坑了。
一度怀疑自己时脑子秀逗了,最后用到的解决方法还是把字母和出现的次数分别拿出来放进了数字中,再用冒泡排序把输出的顺序调好的。虽然也AC了,但是强迫症还是犯了,还有更好的解法。这里也把旧的代码放进来。
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class PTA63 {
public static void main(String[] args) {
Map<String, Integer> map = new TreeMap<String, Integer>();
Scanner sc = new Scanner(System.in);
String s ="";
s= sc.nextLine