• 哈夫曼编码_C#代码


    这是链接上一篇文章所写的代码,上一篇链接如下:

    http://www.cnblogs.com/HONT/archive/2013/06/05/3118531.html

    StringToHuffmanCode这个函数相当于把转换步奏打包执行,其中树的一些遍历使用递归实现,由于用了不少.Net3.5的特性,造成看着费劲实在抱歉。。

    public string StringToHuffmanCode(out Dictionary<char, string> key, string str)
    {
        string result = "";
    
        var tmps = GetWeightArray(str);
        //构建权值数组
    
        var tree = CreateHuffmanTree(tmps);
        //构建哈弗曼树,即最优二叉树
    
        var dict = CreateHuffmanDict(tree);
        //构建哈弗曼字典.
    
        result = ToHuffmanCode(str, dict);
        //输出哈弗曼代码
    
        key = dict;
        return result;
    }
    StringToHuffmanCode

    下面给出全部代码

    ===================================================================================

    在VS2012和.Net3.5中 测试通过.

    具体实现:按照权值提取数据 - 转换最优二叉树 - 进行编码 - 返回字典和编码后文件

    首先是Main函数中的代码:

    class Program
    {
            static void Main(string[] args)
            {
                string source = "哈夫曼曼曼曼曼";
    
                Huffman hf = new Huffman();
                Dictionary<char, string> key = null;
                var hfCode = hf.StringToHuffmanCode(out key, source);
    
                Console.WriteLine("--------------------编码与解析");
                Console.WriteLine("编码: "+hfCode);
    
                var text = hf.ToText(hfCode, key);
                Console.WriteLine("解析: " + text);
    
                Console.ReadLine();
            }
    }

    -----------------------------------------------------------------------------------------------------------------------------------

    然后是类里面的代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    
    public class Huffman
    {
        public class Node : IComparable
        {
            /// <summary>
            /// 左子树
            /// </summary>
            public Node LChild { get; set; }
            /// <summary>
            /// 右子树
            /// </summary>
            public Node RChild { get; set; }
            /// <summary>
            /// 权值
            /// </summary>
            public int Weight { get; set; }
            /// <summary>
            /// 原字符
            /// </summary>
            public char Key { get; set; }
    
            public Node()
            {
    
            }
    
            public Node(int weight, char value)
            {
                this.Weight = weight;
                this.Key = value;
            }
            /// <summary>
            /// 实现比较接口,用于排序
            /// </summary>
            public int CompareTo(object obj)
            {
                int result = 0;
                Node tmp = obj as Node;
    
                if (tmp.Weight > this.Weight)
                {
                    result = 1;
                }
                else if (tmp.Weight < this.Weight)
                {
                    result = -1;
                }
    
                return result;
            }
        }
    
        /// <summary>
        /// 获得权值数组
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public Node[] GetWeightArray(string str)
        {
            List<Node> result = new List<Node>();
    
            char[] charArr = str.ToCharArray();
    
            while (charArr.Length > 0)
            {
                char[] cntChars = null;
                var tmp = charArr.Where(m => m == charArr[0]);
                cntChars = new char[tmp.Count()];
                tmp.ToArray().CopyTo(cntChars, 0);
                charArr = charArr.Where(m => m != tmp.First()).ToArray();
    
                result.Add(new Node(cntChars.Length, cntChars[0]));
            }
    
            return result.ToArray();
        }
    
        /// <summary>
        /// 构建哈弗曼树
        /// </summary>
        /// <param name="sources">权值数组</param>
        /// <returns>返回哈弗曼树根</returns>
        public Node CreateHuffmanTree(Node[] sources)
        {
            Node result = null;
            Node[] nodes = sources;
            bool isNext = true;
    
            while (isNext)
            {
                if (nodes.Length == 2)
                {
                    result = new Node();
                    result.LChild = nodes[0];
                    result.RChild = nodes[1];
                    isNext = false;
                }
    
                Array.Sort(nodes);
                Node n1 = nodes[nodes.Length - 1];
                Node n2 = nodes[nodes.Length - 2];
                Node tmp = new Node();
                tmp.Weight = n1.Weight + n2.Weight;
                tmp.LChild = n1;
                tmp.RChild = n2;
    
                Node[] tmpNds = new Node[nodes.Length - 1];
                Array.Copy(nodes, 0, tmpNds, 0, nodes.Length - 1);
                tmpNds[tmpNds.Length - 1] = tmp;
    
                nodes = tmpNds;
            }
    
            return result;
        }
    
        /// <summary>
        /// 字符串转换为哈弗曼代码.当然可以改成二进制数据
        /// </summary>
        /// <param name="key">编码字典</param>
        /// <param name="str">传入字符串</param>
        /// <returns>编码后的字符串</returns>
        public string StringToHuffmanCode(out Dictionary<char, string> key, string str)
        {
            string result = "";
    
            var tmps = GetWeightArray(str);
    
            var tree = CreateHuffmanTree(tmps);
            var dict = CreateHuffmanDict(tree);
    
            foreach (var item in dict)
            {
                Console.WriteLine(item);
            }
    
            result = ToHuffmanCode(str, dict);
    
            key = dict;
            return result;
        }
    
        /// <summary>
        /// 创建哈弗曼代码字典
        /// </summary>
        /// <param name="hTree">哈弗曼树</param>
        /// <returns></returns>
        public Dictionary<char, string> CreateHuffmanDict(Node hTree)
        {
            return CreateHuffmanDict("", hTree);
        }
    
        private Dictionary<char, string> CreateHuffmanDict(string code, Node hTree)
        {
            Dictionary<char, string> result = new Dictionary<char, string>();
    
            if (hTree.LChild == null && hTree.RChild == null)
            {
                result.Add(hTree.Key, code);
            }
            else
            {
                var dictL = CreateHuffmanDict(code + "0", hTree.LChild);
                var dictR = CreateHuffmanDict(code + "1", hTree.RChild);
    
                foreach (var item in dictL)
                {
                    result.Add(item.Key, item.Value);
                }
    
                foreach (var item in dictR)
                {
                    result.Add(item.Key, item.Value);
                }
            }
    
            return result;
        }
    
        /// <summary>
        /// 源字符串转换到哈弗曼代码
        /// </summary>
        /// <param name="source">源字符串</param>
        /// <param name="hfdict">哈弗曼代码字典</param>
        /// <returns>编译后代码</returns>
        public string ToHuffmanCode(string source, Dictionary<char, string> hfdict)
        {
            string result = "";
    
            for (int i = 0; i < source.Length; i++)
            {
                result += hfdict.First(m => m.Key == source[i]).Value;
            }
    
            return result;
        }
    
        /// <summary>
        /// 解析回字符串
        /// </summary>
        /// <param name="code">哈弗曼代码</param>
        /// <param name="hfdict">哈弗曼代码字典</param>
        /// <returns>解析后字符串</returns>
        public string ToText(string code, Dictionary<char, string> hfdict)
        {
            string result = "";
    
            for (int i = 0; i < code.Length; )
            {
                foreach (var item in hfdict)
                {
                    if (    code[i] == item.Value[0]
                        && item.Value.Length + i <= code.Length)
                    {
                        char[] tmpArr = new char[item.Value.Length];
    
                        Array.Copy(code.ToCharArray(), i, tmpArr, 0, tmpArr.Length);
    
                        if (new String(tmpArr) == item.Value)
                        {
                            result += item.Key;
                            i += item.Value.Length;
                            break;
                        }
                    }
                }
            }
    
            return result;
        }
    }
  • 相关阅读:
    tomcat部署项目时 报错Tomcat version 7.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5 and 6 Web modules
    异常:Caused by: java.lang.NoClassDefFoundError: org/springframework/web/context/WebApplicationContext
    java安全管理器SecurityManager介绍
    Mybatis框架基础支持层——反射工具箱之Reflector&ReflectorFactory(3)
    Mybatis框架基础支持层——解析器模块(2)
    Mybatis框架可视化(1)
    JDK动态代理简单使用(2)
    代理(1)
    动态代理源码分析(3)
    springboot(十七)-使用Docker部署springboot项目
  • 原文地址:https://www.cnblogs.com/hont/p/3118679.html
Copyright © 2020-2023  润新知