Advertisement
yetisergey

Untitled

May 3rd, 2019
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.09 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4.  
  5. namespace hoff
  6. {
  7.     public class Hoffman
  8.     {
  9.         const char EMPTY_CHAR = '\0';
  10.  
  11.         public Hoffman(string text)
  12.         {
  13.             if (string.IsNullOrEmpty(text))
  14.             {
  15.                 throw new Exception("empty text");
  16.             }
  17.  
  18.             var originText = string.Concat(text.Where(u => !char.IsPunctuation(u)).ToList());
  19.  
  20.             SetDictionary(originText);
  21.         }
  22.  
  23.         public string GetEncriptedText(string text)
  24.         {
  25.             return string.Concat(GetEncriptedSymbols(text).ToList());
  26.         }
  27.  
  28.         public string GetDecriptedText(string text)
  29.         {
  30.             return string.Concat(GetDecriptedSymbols(text).ToList());
  31.         }
  32.  
  33.         public void PrintDictionary()
  34.         {
  35.             foreach (var item in dictionary)
  36.             {
  37.                 Console.WriteLine($"{item.Key} - {item.Value}");
  38.             }
  39.         }
  40.  
  41.         private Dictionary<char, string> dictionary = new Dictionary<char, string>();
  42.  
  43.         private int dictionaryMinCodeLength => dictionary.OrderBy(u => u.Value.Length).FirstOrDefault().Value.Length;
  44.  
  45.         private Dictionary<char, string> SetDictionary(string text)
  46.         {
  47.             var mapKeys = text
  48.                 .GroupBy(u => u)
  49.                 .Select(u => new Point { Key = u.Key, Count = u.Count() })
  50.                 .OrderBy(u => u.Count)
  51.                 .ThenBy(u => u.Key)
  52.                 .ToList();
  53.  
  54.             while (mapKeys.Count > 1)
  55.             {
  56.                 var child1 = mapKeys[0];
  57.                 var child2 = mapKeys[1];
  58.                 mapKeys.RemoveAt(0);
  59.                 mapKeys.RemoveAt(0);
  60.                 mapKeys.Add(new Point
  61.                 {
  62.                     Count = child1.Count + child2.Count,
  63.                     LeftPoint = child1,
  64.                     RightPoint = child2
  65.                 });
  66.  
  67.                 mapKeys = mapKeys
  68.                     .OrderBy(u => u.Count)
  69.                     .ToList();
  70.             }
  71.  
  72.             var parentPoint = mapKeys.FirstOrDefault();
  73.  
  74.             if (parentPoint == null)
  75.             {
  76.                 throw new Exception("can't find parent point");
  77.             }
  78.  
  79.             SetPointCodes(parentPoint);
  80.             GetPointCodes(parentPoint);
  81.  
  82.             return dictionary;
  83.         }
  84.  
  85.         private IEnumerable<string> GetEncriptedSymbols(string text)
  86.         {
  87.             foreach (var item in text)
  88.                 yield return dictionary[item];
  89.         }
  90.  
  91.         private IEnumerable<char> GetDecriptedSymbols(string text)
  92.         {
  93.             var tempLength = dictionaryMinCodeLength;
  94.             for (int i = 0; i < text.Length; i++)
  95.             {
  96.                 char key = EMPTY_CHAR;
  97.                 var valueLength = dictionaryMinCodeLength;
  98.                 while (key == EMPTY_CHAR)
  99.                 {
  100.                     var code = string.Concat(text.Skip(i).Take(valueLength).ToList());
  101.                     key = dictionary.FirstOrDefault(u => u.Value == code).Key;
  102.                     if (key == EMPTY_CHAR)
  103.                         valueLength++;
  104.                 }
  105.                 i += (valueLength - 1);
  106.                 yield return key;
  107.             }
  108.         }
  109.  
  110.         private void GetPointCodes(Point parentPoint)
  111.         {
  112.             if (parentPoint.Key != EMPTY_CHAR)
  113.                 dictionary.Add(parentPoint.Key, parentPoint.Code);
  114.  
  115.             if (parentPoint.LeftPoint != null)
  116.                 GetPointCodes(parentPoint.LeftPoint);
  117.  
  118.             if (parentPoint.RightPoint != null)
  119.                 GetPointCodes(parentPoint.RightPoint);
  120.         }
  121.  
  122.         private static void SetPointCodes(Point point)
  123.         {
  124.             if (point.LeftPoint != null)
  125.             {
  126.                 point.LeftPoint.Code = point.Code + "0";
  127.                 SetPointCodes(point.LeftPoint);
  128.             }
  129.  
  130.             if (point.RightPoint != null)
  131.             {
  132.                 point.RightPoint.Code = point.Code + "1";
  133.                 SetPointCodes(point.RightPoint);
  134.             }
  135.         }
  136.     }
  137. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement