【校招笔试】字符编码(哈夫曼树)

来源:互联网 发布:熊猫tv直播软件 编辑:程序博客网 时间:2024/05/13 06:24
时间限制:1秒 空间限制:32768K 热度指数:629
本题知识点: 贪心

题目描述:

请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短。

输入描述

每组数据一行,为待编码的字符串。保证字符串长度小于等于1000。

输出描述

一行输出最短的编码后长度。

输入例子

MT-TECH-TEAM

输出例子

33


解题思路(以输入例子为例)

  1. 统计各个字符出现的个数,如下:
    M(2), T(3), E(2), C(1), H(1), A(1), -(2)
  2. 画出哈夫曼树,如下:
    这里写图片描述
  3. 发现编码后字符串的长度等于:各个非叶子结点值之和(2+3+5+4+7+12)
  4. 利用这个,用HashMap存字符出现的个数,PriorityQueue优先队列选出两个最小的结点值

代码

import java.util.*;//比较器(没有用)class Comparators {    public static Comparator getComparator() {        return new Comparator() {            @Override            public int compare(Object o1, Object o2) {                if (o1 instanceof Integer) {                    return compare( (Integer) o1, (Integer) o2);                } else return 1;            }            public int compare(Integer s1, Integer s2) {                return s2-s1;            }        };    }}public class Main {    /*        测试代码     */    public static void main(String []args){        Scanner sc = new Scanner(System.in);        while(sc.hasNext()){            String str = sc.nextLine();            HashMap<Character, Integer> map = new HashMap<Character, Integer>();            for(int i = 0; i < str.length(); i++) {                Character c = str.charAt(i);                if (map.containsKey(c)) {                    map.put(c, map.get(c)+1);                } else {                    map.put(c, 1);                }            }            PriorityQueue<Integer> queue = new PriorityQueue<Integer>();            for(Character i : map.keySet()) {                queue.add(map.get(i));            }            int ans = 0;            while(!queue.isEmpty()) {                int num1 = queue.poll();                int num2 = queue.poll();                ans += (num1+num2);                if(!queue.isEmpty())queue.add(num1+num2);            }            System.out.println(ans);        }    }}
0 0
原创粉丝点击