• 哈夫曼编码C#版做的改进,可用于简单加密


    就是把01010的数据换成了可以自定义的字典.如果字典数量比字符数量多,就会把多出来的字典去掉。

    如果字典里值有重复的话,也会把重复值去掉。

    其实就是把左右子树变成数组,但其他对二叉树的操作就会受影响了。

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

    具体代码如下

    class Program
    {
        static void Main(string[] args)
        {
            string source = "哈弗曼曼曼曼曼";
    
            Huffman hf = new Huffman("qwer".ToCharArray());
            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();
        }
    }
    Main函数代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace ConsoleApplication1
    {
        public class Huffman
        {
            public class Node : IComparable
            {
                public Node[] Child { get; set; }
    
                public int Weight { get; set; }
    
                public char Key { get; set; }
    
                public Node()
                {
    
                }
    
                public Node(int weight, char value)
                {
                    this.Weight = weight;
                    this.Key = value;
                }
    
                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;
                }
            }
    
            private char[] mDict;
            private char[] mCntDict;
    
            public Huffman(char[] dict)
            {
                this.mDict = dict.Distinct().ToArray();
    
                mCntDict = mDict;
            }
    
            public Node[] GetWeightArray(string str)
            {
                List<Node> result = new List<Node>();
    
                char[] charArr = str.ToCharArray();
    
                if (charArr.Length < mDict.Length)
                {
                    char[] tmp = new char[charArr.Length];
    
                    Array.Copy(mDict, 0, tmp, 0, charArr.Length);
    
                    mCntDict = tmp;
                }
    
                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>
            /// 两个一放变成N个一放
            /// </summary>
            public Node CreateHuffmanTree(Node[] sources)
            {
                Node result = null;
                Node[] nodes = sources;
    
                while (true)
                {
                    if (nodes.Length <= mCntDict.Length)
                    {
                        result = new Node();
                        result.Child = nodes;
                        break;
                    }
    
                    Array.Sort(nodes);
                    Node tmp = new Node();
                    tmp.Child = new Node[mCntDict.Length];
    
                    for (int i = nodes.Length - 1, j=0; i >= 0; i--, j++)
                    {
                        if (j < mCntDict.Length)
                        {
                            tmp.Weight += nodes[i].Weight;
                            tmp.Child[j] = nodes[i];
                        }
                        else
                        {
                            break;
                        }
                    }
    
                    Node[] tmpNds = new Node[nodes.Length - (mCntDict.Length-1)];
                    Array.Copy(nodes, 0, tmpNds, 0, nodes.Length - (mCntDict.Length - 1));
                    tmpNds[tmpNds.Length - 1] = tmp;
    
                    nodes = tmpNds;
                }
    
                return result;
            }
    
            public string StringToHuffmanCode(out Dictionary<char, string> key, string str)
            {
                string result = "";
    
                var tmps = GetWeightArray(str);
    
                var tree = CreateHuffmanTree(tmps);
                var dict = CreateHuffmanCode(tree);
    
                foreach (var item in dict)
                {
                    Console.WriteLine(item);
                }
    
                result = ToHuffmanCode(str, dict);
    
                key = dict;
                return result;
            }
    
            public Dictionary<char, string> CreateHuffmanCode(Node hTree)
            {
                return CreateHuffmanCode("", hTree);
            }
    
            private Dictionary<char, string> CreateHuffmanCode(string code, Node hTree)
            {
                Dictionary<char, string> result = new Dictionary<char, string>();
    
                if (hTree.Child == null)
                {
                    result.Add(hTree.Key, code);
                }
                else
                {
                    for (int i = 0; i < hTree.Child.Length; i++)
                    {
                        var tmpDict = CreateHuffmanCode(code+mCntDict[i], hTree.Child[i]);
    
                        foreach (var item in tmpDict)
                        {
                            result.Add(item.Key, item.Value);
                        }
                    }
                }
    
                return result;
            }
    
            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;
            }
    
            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;
            }
        }
    }
    Huffman类中代码
  • 相关阅读:
    桥接模式
    单例模式
    迭代器模式
    组合模式
    备忘录模式
    适配器模式
    状态模式
    观察者模式
    golang 字符串统计
    go bytes缓冲区使用介绍 -转自https://www.cnblogs.com/--xiaoyao--/p/5122138.html
  • 原文地址:https://www.cnblogs.com/hont/p/3118686.html
Copyright © 2020-2023  润新知