zoukankan      html  css  js  c++  java
  • 哈夫曼树压缩C#算法(huffman)

    算法原理:http://www.cnblogs.com/skywang12345/p/3706833.html。

    上代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    using System.Threading;
    using System.IO;
    using System.Web.Script;
    using System.Web.Script.Serialization;
    
    namespace ConsoleApplication2
    {
        public class Program
        {
            public static void Main()
            {
                string content = @"bacbccddeeeddee";
                Console.WriteLine("需要压缩的内容(长度:" + content.Length + "):");
                Console.WriteLine(content);
                Console.WriteLine();
    
                HuffmanTree huffman = new HuffmanTree();
    
                string compressionString = huffman.Compression(content);
                Console.WriteLine("压缩后的内容(长度:" + compressionString.Length + "):");
                Console.WriteLine(compressionString);
                Console.WriteLine();
    
                string unZipContent = huffman.Unzip(compressionString);
                Console.WriteLine("解压后的的内容:");
                Console.WriteLine(unZipContent);
                Console.Read();
            }
        }
    
        public class HuffmanTreeInfo
        {
            public string ZipCode { get; set; }
            public string ZipCodeRemainder { get; set; }
            public Dictionary<string, char> UnZipDictionary { get; set; }
        }
    
        public class HuffmanTree
        {
            public class HuffmanNote
            {
                public int Weight { get; set; }
                public char Word { get; set; }
                public HuffmanNote LeftNote { get; set; }
                public HuffmanNote RightNote { get; set; }
                public char HuffmanCode { get; set; }
            }
    
            public string Compression(string content)
            {
                HuffmanNote huffmanNote = CreateHuffmanTree(CreateWordWeightDictionary(content));
    
                Dictionary<char, string> encodeDictionary = new Dictionary<char, string>();
                CreateWordCodeDictionay(huffmanNote, "", encodeDictionary);
    
                StringBuilder sb = new StringBuilder(content.Length);
                foreach (var item in content)
                {
                    sb.Append(encodeDictionary[item]);
                }
    
                string huffmanCode = sb.ToString();
    
                HuffmanTreeInfo huffmanTreeInfo = new HuffmanTreeInfo();
                huffmanTreeInfo.ZipCodeRemainder = huffmanCode.Substring(huffmanCode.Length - huffmanCode.Length % 8);
                huffmanTreeInfo.ZipCode = HuffmanCodeToByte(huffmanCode.Substring(0, huffmanCode.Length - huffmanCode.Length % 8));
                huffmanTreeInfo.UnZipDictionary = CreateUnZipDictionary(encodeDictionary);
    
                return ObjectToJson(huffmanTreeInfo);
            }
    
            private string ObjectToJson(object obj)
            {
                return new JavaScriptSerializer().Serialize(obj);
            }
    
            private T JsonToObject<T>(string json)
            {
                return new JavaScriptSerializer().Deserialize<T>(json);
            }
    
            private List<HuffmanNote> CreateWordWeightDictionary(string content)
            {
                Dictionary<char, int> wordWeightDictionary = new Dictionary<char, int>();
    
                foreach (var item in content)
                {
                    if (wordWeightDictionary.ContainsKey(item))
                    {
                        wordWeightDictionary[item] += 1;
                    }
                    else
                    {
                        wordWeightDictionary[item] = 1;
                    }
                }
    
                List<HuffmanNote> huffmanNoteList = new List<HuffmanNote>();
                foreach (var item in wordWeightDictionary)
                {
                    huffmanNoteList.Add(new HuffmanNote()
                    {
                        Weight = item.Value,
                        Word = item.Key
                    });
                }
                return huffmanNoteList;
            }
    
            public string Unzip(string content)
            {
                HuffmanTreeInfo huffmanTreeInfo = JsonToObject<HuffmanTreeInfo>(content);
    
                StringBuilder sb = new StringBuilder(huffmanTreeInfo.ZipCode.Length);
                for (int i = 0; i < huffmanTreeInfo.ZipCode.Length; i++)
                {
                    sb.Append(Convert.ToString((int)huffmanTreeInfo.ZipCode[i], 2).PadLeft(8, '0'));
                }
                string huffmanCodes = sb.ToString() + huffmanTreeInfo.ZipCodeRemainder;
    
                StringBuilder decode = new StringBuilder(huffmanCodes.Length);
                string temp = string.Empty;
                for (int i = 0; i < huffmanCodes.Length; i++)
                {
                    temp += huffmanCodes[i].ToString();
                    if (huffmanTreeInfo.UnZipDictionary.ContainsKey(temp))
                    {
                        decode.Append(huffmanTreeInfo.UnZipDictionary[temp]);
                        temp = string.Empty;
                    }
                }
                return decode.ToString();
            }
    
            private string HuffmanCodeToByte(string huffmanCodes)
            {
                StringBuilder sb = new StringBuilder(huffmanCodes.Length);
                for (int i = 0; i*8 < huffmanCodes.Length; i++)
                {
                    sb.Append((char)Convert.ToInt32(huffmanCodes.Substring(i * 8, 8), 2));
                }
                return sb.ToString();
            }
    
            private Dictionary<string, char> CreateUnZipDictionary(Dictionary<char, string> encodeDictionary)
            {
                Dictionary<string, char> unZipDictionary = new Dictionary<string, char>();
                foreach (var item in encodeDictionary)
                {
                    unZipDictionary.Add(item.Value, item.Key);
                }
                return unZipDictionary;
            }
    
            private HuffmanNote CreateHuffmanTree(List<HuffmanNote> huffmanNoteList)
            {
                if (huffmanNoteList.Count == 1)
                {
                    return huffmanNoteList[0];
                }
    
                var huffmanNoteListBySort = huffmanNoteList.OrderBy(o => o.Weight).ToList();
    
                var minWeight2Note = huffmanNoteListBySort.Take(2).ToList();
                huffmanNoteListBySort.RemoveAt(0);
                huffmanNoteListBySort.RemoveAt(0);
    
                var leftNote = minWeight2Note[0];
                leftNote.HuffmanCode = '0';
    
                var rightNote = minWeight2Note[1];
                rightNote.HuffmanCode = '1';
    
                var newNote = new HuffmanNote()
                {
                    LeftNote = leftNote,
                    RightNote = rightNote,
                    Weight = leftNote.Weight + rightNote.Weight
                };
    
                huffmanNoteListBySort.Add(newNote);
    
                return CreateHuffmanTree(huffmanNoteListBySort);
            }
    
            private void CreateWordCodeDictionay(HuffmanNote huffmanNote, string HuffmanCode, Dictionary<char, string> encodeDictionary)
            {
                if (huffmanNote.LeftNote == null)
                {
                    encodeDictionary[huffmanNote.Word] = HuffmanCode.Substring(1) + huffmanNote.HuffmanCode;//HuffmanCode.Substring(1) 为什么有这句呢  因为char默认值是\0  所以这里要把第一个字符\0去掉
                    return;
                }
                HuffmanCode += huffmanNote.HuffmanCode;
    
                CreateWordCodeDictionay(huffmanNote.LeftNote, HuffmanCode, encodeDictionary);
                CreateWordCodeDictionay(huffmanNote.RightNote, HuffmanCode, encodeDictionary);
            }
        }
    }
  • 相关阅读:
    假期进度报告2
    假期进度报告1
    JavaScript下判断元素是否存在
    浪潮之巅阅读笔记06
    浪潮之巅阅读笔记05
    浪潮之巅阅读笔记04
    【C语言】C语言简介
    iOS网络监测方法
    iOS常用手势识别器
    【CoreData】 简单地使用
  • 原文地址:https://www.cnblogs.com/bbvi/p/5039408.html
Copyright © 2011-2022 走看看