哈夫曼编码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类中代码

 

posted @ 2013-06-05 12:14  HONT  阅读(1066)  评论(0编辑  收藏  举报