思路:哈夫曼编码
代码:
import java.util.Scanner;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
//知识点1: 树节点,自定义比较规则
class Node implements Comparable<Node>{
public int val;
public Node left;
public Node right;
Node(int val){
this.val = val;
}
@Override
public int compareTo(Node o) {
return this.val-o.val;
}
}
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String str = sc.nextLine().trim();
//知识点2: Map计数统计
Map<Character, Integer> map = new HashMap<Character, Integer>();
for(int i=0; i<str.length(); i++){
char ch = str.charAt(i);
if(map.containsKey(ch)){
int val = map.get(ch);
map.put(ch, ++val);
}else{
map.put(ch, 1);
}
}
//知识点3: 优先队列的使用!!!(最重要的知识点)
PriorityQueue<Node> queue = new PriorityQueue<Node>();
for(char ch : map.keySet()){
Node node = new Node(map.get(ch));
queue.offer(node);
}
//知识点4: 哈夫曼编码
while(queue.size()>1){
Node node1 = queue.poll();
Node node2 = queue.poll();
Node nodeNew = new Node(node1.val+node2.val);
nodeNew.left = node1;
nodeNew.right = node2;
queue.offer(nodeNew);
}
Node root = queue.poll();
System.out.println(countLength(root, 0));
}
}
//知识点5: 统计编码长度
public static int countLength(Node node, int level){
if(node.left==null && node.right==null){
return node.val*level;
}
return countLength(node.left, level+1)+countLength(node.right, level+1);
}
}