• 霍夫曼树,霍夫曼编码


    关于霍夫曼树和霍夫曼编码的背景知识,这里不讲述。本文只记录代码。

    package org.lyk.entities;
    
    import org.lyk.entities.List.Node;
    import org.omg.CORBA.Current;
    
    public class HuffmanTree<T extends Comparable<T>>
    {
        class PriorityNode implements Comparable<PriorityNode>
        {
            T data;
            int count = 0;
    
            public PriorityNode(T data, int count)
            {
                super();
                this.data = data;
                this.count = count;
            }
    
            @Override
            public int hashCode()
            {
                final int prime = 31;
                int result = 1;
                result = prime * result + getOuterType().hashCode();
                result = prime * result + count;
                result = prime * result + ((data == null) ? 0 : data.hashCode());
                return result;
            }
    
            @Override
            public boolean equals(Object obj)
            {
                if (this == obj)
                    return true;
                if (obj == null)
                    return false;
                if (getClass() != obj.getClass())
                    return false;
                PriorityNode other = (PriorityNode) obj;
                if (!getOuterType().equals(other.getOuterType()))
                    return false;
    
                if (data == null)
                {
                    if (other.data != null)
                        return false;
                } else if (!data.equals(other.data))
                    return false;
                return true;
            }
    
            private HuffmanTree getOuterType()
            {
                return HuffmanTree.this;
            }
    
            @Override
            public int compareTo(HuffmanTree<T>.PriorityNode o)
            {
                if (this.count < o.count)
                    return -1;
                else if (this.count > o.count)
                    return 1;
                else
                    return 0;
            }
        }
    
        class HuffmanNode
        {
            PriorityNode data;
            HuffmanNode left;
            HuffmanNode right;
            String code = "?";
    
            public HuffmanNode(PriorityNode data)
            {
                this.data = data;
            }
        }
    
        private java.util.List<PriorityNode> pnList = null;
        private java.util.List<HuffmanNode> hfList = null;
        private StringBuffer codes = new StringBuffer();
    
        public void setPriorityList(T[] source)
        {
            java.util.List<PriorityNode> pnList = new java.util.ArrayList<>();
            for (T item : source)
            {
                PriorityNode temp = new PriorityNode(item, 1);
                if (!pnList.contains(temp))
                {
                    pnList.add(temp);
                } else
                {
                    int index = pnList.indexOf(temp);
                    PriorityNode pn = pnList.get(index);
                    pn.count++;
                }
            }
            pnList.sort((pn1, pn2) ->
            {
                return pn1.compareTo(pn2);
            });
            this.pnList = pnList;
        }
    
        public void setHuffmanList()
        {
            java.util.List<HuffmanNode> hfList = new java.util.ArrayList<>();
            for (PriorityNode item : this.pnList)
            {
                HuffmanNode temp = new HuffmanNode(item);
                hfList.add(temp);
            }
            this.hfList = hfList;
        }
    
        public void setHuffmanTree()
        {
            while (this.hfList.size() > 1)
            {
                HuffmanNode node0 = this.hfList.get(0);
                HuffmanNode node1 = this.hfList.get(1);
                PriorityNode pn = new PriorityNode(null, node0.data.count + node1.data.count);
                HuffmanNode newHFNode = new HuffmanNode(pn);
                newHFNode.code = "?";
    
                if (node0.data.count < node1.data.count)
                {
                    node0.code = "0";
                    newHFNode.left = node0;
                    node1.code = "1";
                    newHFNode.right = node1;
                } else
                {
                    node1.code = "0";
                    newHFNode.left = node1;
                    node0.code = "1";
                    newHFNode.right = node0;
                }
    
                this.hfList.remove(0);
                this.hfList.remove(0);
                this.hfList.add(newHFNode);
                this.hfList.sort((hfNode1, hfNode2) ->
                {
                    if (hfNode1.data.count < hfNode2.data.count)
                        return -1;
                    else if (hfNode1.data.count > hfNode2.data.count)
                        return 1;
                    else
                        return 0;
                });
            }
        }
    
        public void encodeHuffmanTree()
        {
            this.encodeInternal(this.hfList.get(0), "?");
            this.getAllCodes(this.hfList.get(0));
            //System.out.println(this.codes.toString());
        }
    
        private void encodeInternal(HuffmanNode hfNode, String preCode)
        {
            if ("?".equals(hfNode.code))
            {
                if (null != hfNode.left)
                    encodeInternal(hfNode.left, "");
                if (null != hfNode.right)
                    encodeInternal(hfNode.right, "");
            } else
            {
                // 非根元素
                hfNode.code = preCode + hfNode.code;
                if (null != hfNode.left)
                    encodeInternal(hfNode.left, hfNode.code);
                if (null != hfNode.right)
                    encodeInternal(hfNode.right, hfNode.code);
            }
        }
    
        private void getAllCodes(HuffmanNode node)
        {
            if (null == node.left && null == node.right)
            { 
                this.codes.append(node.code);
            }
            if (null != node.left)
                getAllCodes(node.left);
            if (null != node.right)
                getAllCodes(node.right);
        }
    
        public String decode(String codes)
        {
            char[] charArray = codes.toCharArray();
            HuffmanNode current = this.hfList.get(0);
            for (char c : charArray)
            {
                if ('0' == c)
                    current = current.left;
                else if ('1' == c)
                    current = current.right;
    
                if (null == current.left && null == current.right)
                {
                    System.out.print(current.data.data);
                    current = this.hfList.get(0);
                }
            }
            return null;
        }
    
        public void find(T item)
        {
            this.findInternal(this.hfList.get(0), item);
        }
    
        private void findInternal(HuffmanNode node, T item)
        {
            if (null == node.left && null == node.right)
            {
                if (node.data.data.equals(item))
                    this.codes.append(node.code);
            }
    
            if (null != node.left)
                findInternal(node.left, item);
            if (null != node.right)
                findInternal(node.right, item);
    
        }
    
        public String encodeContent(T[] charArray)
        {
            for (T c : charArray)
            {
                this.find(c);
            }
    
            return this.codes.toString();
        }
    }

    测试代码:

        public static void main(String[] args) throws Exception
        {
            StringBuffer info = new StringBuffer();
            File inputFile = new File("C:\D\code\Docs\Linux.txt");
            Scanner scanner = new Scanner(new FileInputStream(inputFile));
            scanner.useDelimiter("
    ");
            while(scanner.hasNext())
            {
                info.append(scanner.next());
            } 
            int countSource = info.length();
            HuffmanTree<Character> ht = new HuffmanTree<>();
            char[] _charArray = info.toString().toCharArray();
            Character[] charArray = new Character[_charArray.length];
            for(int i = 0; i < _charArray.length; i++)
            {
                charArray[i] = _charArray[i];
            }
            ht.setPriorityList(charArray);
            ht.setHuffmanList();
            ht.setHuffmanTree();
            ht.encodeHuffmanTree();
            String codes = ht.encodeContent(charArray);
            int countNew = codes.length();
            System.out.println(codes);;
            ht.decode("0000000000000100000100000");
            System.out.println("原长度:" + (countSource*3*8));
            System.out.println("压缩后长度:" + countNew);
            System.out.println("压缩率:" + (new BigDecimal(countNew/(countSource*3*8*1.0)).divide(new BigDecimal("1"),2, RoundingMode.HALF_EVEN)));
            System.out.println("///~ Main done");
            
        }    
  • 相关阅读:
    upc组队赛3 T-net【贪心】
    upc组队赛5 Assembly Required【思维】
    upc组队赛5 Bulbs
    upc组队赛5 Ingenious Lottery Tickets【排序】
    upc组队赛5 Hunter’s Apprentice 【判断多边形边界曲线顺逆时针】
    upc组队赛5 Ground Defense【枚举】
    upc组队赛4 Go Latin
    upc组队赛4 TV Show Game 【2-SAT】
    POJ 3250 Bad Hair Day【单调栈入门】
    016.NET5_MVC_视图组件扩展定制
  • 原文地址:https://www.cnblogs.com/kuillldan/p/6045003.html
Copyright © 2020-2023  润新知