zoukankan      html  css  js  c++  java
  • 哈夫曼编码大全

    题目: 哈夫曼编码大全

    描述:

    关于哈夫曼树的建立,编码,解码。

    输入

    第一行输入数字N,代表总共有多少个字符以及权值

    第二第三行分别是一行字符串,以及每个字符对应的权值

    接下来输入一个数M,表示接下来有M行字符串,要求你对每个字符串进行编码

    再输入一个数X,表示接下来有X行编码,要求你对每行编码进行解码

    输出

    第一行输出所有节点的权重

    接下来输出N行,每行以 “a:001”的格式输出每个字符对应的编码

    接着输出M行,对输入的字符串的编码结果

    最后,输出X行的解码结果

    输入样例

    6
    abcdef
    50 10 5 5 20 10
    2
    abcdef
    defabaabbc
    2
    011001100100110110101101100
    1100011000110101100101100

    输出样例

     

    50 10 5 5 20 10 10 20 30 50 100
    a:0
    b:100
    c:1100
    d:1101
    e:111
    f:101
    010011001101111101
    11011111010100001001001100
    accbdfadb
    cacadacfb

    import java.util.Scanner;
    
    
    /**
     * 哈弗曼编码大全
     * @author 邹龄晋
    6
    abcdef
    50 10 5 5 20 10
     *
     */
    public class Demo {
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            int n = sc.nextInt();
            int j;
            HFMTree ht = new HFMTree(n);
            int data[] = new int[n];
            Code code[] = new Code[n];
            String str = sc.next();
            for(int i=0;i<n;i++){
                j = sc.nextInt();
                data[i] = j;
            }
            ht.init(data);
            ht.create();
            //ht.PrintTree();
            ht.Quan();
            for(int i=0;i<n;i++){
                System.out.print(str.charAt(i)+":");
                //ht.PrintCode(i);
                //System.out.println();
                String fff=ht.PrintCode3(i,"");
                code[i] = new Code(str.charAt(i),fff);
                System.out.println(fff);
            }
            //编码
            int k=sc.nextInt();
            while(k>0){
                String s = sc.next();
                for(int i=0;i<s.length();i++){
                    int m = str.indexOf(s.charAt(i));
                    ht.PrintCode(m);
                }
                k--;
            }
            
            k = sc.nextInt();
            String st;
            int d;
            String ss = sc.nextLine();
            while(k>0){
                int q = 0;
                ss = sc.nextLine();
                for(int m=1;m<=ss.length();m++){
                    st = ss.substring(q,m);
                    for(d=0;d<code.length;d++){
                        if(st.equals(code[d].getCode())){
                            System.out.print(code[d].getCh());
                            break;
                        }
                    }
                    if(d < code.length){
                        q = m;
                        //System.out.println(m);
                    }
                }
                System.out.println();
                k --;
            }
        }
    
    }
    class HFMTree{
        //属性
        private int n;//结点数
        private HN[] hn;//结点数组
        public int getN() {
            return n;
        }
        public void setN(int n) {
            this.n = n;
        }
        public HN[] getHn() {
            return hn;
        }
        public void setHn(HN[] hn) {
            this.hn = hn;
        }
        public HFMTree(int n){
            this.n = n;
            this.hn = new HN[2*n-1];//有n个结点,创建2*n-1个数组空间
            for(int i=0;i<2*n-1;i++){
                hn[i] = new HN();//创建2*n-1个HN的对象
            }
        }
        
        public void init(int data[]){
            for(int i=0;i<data.length;i++){
                hn[i].setWeight(data[i]);
            }
        }
        //创建哈弗曼树
        public void create(){
            int min1=0,min2=0,i,j,temp;
            for(i=n;i<2*n-1;i++){
                for(j=0;j<i;j++){
                    if(hn[j].getParent()==0){
                        min1=j;
                        break;
                    }
                }
                j++;
                for(;j<i;j++){
                    if(hn[j].getParent()==0){
                        min2=j;
                        break;
                    }
                }
                if(hn[min1].getWeight()>hn[min2].getWeight()){
                    temp = min1;
                    min1 = min2;
                    min2 = temp;
                }
                j++;
                for(;j<i;j++){
                    if(hn[j].getParent()==0){
                        if(hn[j].getWeight()<hn[min1].getWeight()){
                            min2 = min1;
                            min1 = j;
                        }else{
                            if(hn[j].getWeight()<hn[min2].getWeight()){
                                min2 = j;
                            }
                            
                        }
                    }
                }
                
                //上面的代码找到两个最小的,写到作为第i个左右孩子
                hn[i].setWeight(hn[min1].getWeight()+hn[min2].getWeight());
                hn[i].setLeft(min1);
                hn[i].setRight(min2);
                hn[min1].setParent(i);
                hn[min2].setParent(i);
                hn[i].setParent(0);
            }
        }
        
        //输出哈弗曼树
        public void PrintTree(){
            for(int i=0;i<2*n-1;i++){
                System.out.println(i+"	"+hn[i].getWeight()+"	"+hn[i].getLeft()+"	"+hn[i].getRight()+"	"+hn[i].getParent());
            }
        }
        //输出权数
        public void Quan(){
            for(int i=0;i<2*n-1;i++){
                System.out.print(hn[i].getWeight()+" ");
            }
            System.out.println();
        }
        //输出字符对应的代码方法一:
        public void PrintCode(int i){
            if(hn[i].getParent()==0)
                return;
            int p = hn[i].getParent();
            
            PrintCode(p);
            if(hn[p].getLeft()==i){
                System.out.print(0);
            }else{
                System.out.print(1);
            }
        }
        //输出字符对应的代码方法二:
        public String PrintCode2(int i){
            String codes="";
            if(hn[i].getParent()==0)
                return "";
            int p = hn[i].getParent();
            
            PrintCode(p);
            if(hn[p].getLeft()==i){
                codes+="0";
            }else{
                codes+="1";
            }
            return codes;
        }
        //方法三:
        public String PrintCode3(int i,String codes){
            while(hn[i].getParent() != 0){
                if(hn[hn[i].getParent()].getLeft() == i){
                    codes = codes + "0";
                }
                if(hn[hn[i].getParent()].getRight() == i){
                    codes = codes + "1";
                }
                i = hn[i].getParent();
            }
            String codes1 = "";
            for(int j=codes.length()-1;j>=0;j--){
                codes1 = codes1 + codes.charAt(j);
            }
            return codes1;
        }
        
        
    }
    class HN{
        private int weight;
        private int left;
        private int right;
        private int parent;
        public int getWeight() {
            return weight;
        }
        public void setWeight(int weight) {
            this.weight = weight;
        }
        public int getLeft() {
            return left;
        }
        public void setLeft(int left) {
            this.left = left;
        }
        public int getRight() {
            return right;
        }
        public void setRight(int right) {
            this.right = right;
        }
        public int getParent() {
            return parent;
        }
        public void setParent(int parent) {
            this.parent = parent;
        }
        public HN(int weight){
            this.weight = weight;
            this.left = 0;
            this.right = 0;
            this.parent = 0;
        }
        public HN(){
            this.weight = 0;
            this.left = 0;
            this.right = 0;
            this.parent = 0;
        }
    }
    class Code{
        private char ch;
        private String code;
        public char getCh() {
            return ch;
        }
        public void setCh(char ch) {
            this.ch = ch;
        }
        public String getCode() {
            return code;
        }
        public void setCode(String code) {
            this.code = code;
        }
        public Code(char ch,String code){
            this.ch = ch;
            this.code = code;
        }
    }
  • 相关阅读:
    Django remedy a security issue refer dos attack
    AppScan8.7的两个细节亮点
    redis的使用
    IDEA使用技巧
    记录tips
    Scala实现wordcount
    Scala学习笔记1
    linux系统下访问window本地数据库
    python国内使用豆瓣下载源和linux常用的命令
    hadoop集群开启和停止执行命令
  • 原文地址:https://www.cnblogs.com/zoulingjin/p/8677061.html
Copyright © 2011-2022 走看看