Margoshinka

Архиватор

Oct 11th, 2023
839
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 12.66 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using System.Text;
  6.  
  7. namespace Архиватор
  8. {
  9.     class BitBuffer
  10.     {
  11.         private const int BufferSize = 8;
  12.         private byte[] buffer = new byte[1];
  13.         private byte currBuf = new byte();
  14.         private int bufferCount = 0;
  15.         BinaryWriter writer = null;
  16.  
  17.         public BitBuffer(BinaryWriter writer)
  18.         {
  19.             this.writer = writer;
  20.         }
  21.         public void PushBit(bool bit)
  22.         {
  23.            
  24.             currBuf <<= 1;
  25.             if (bit)
  26.             {
  27.                 currBuf |= 1;
  28.             }
  29.  
  30.             bufferCount++;
  31.  
  32.             if (bufferCount >= BufferSize)
  33.             {
  34.                 FlushBuffer();
  35.             }
  36.         }
  37.  
  38.         public void Convert(string bits)
  39.         {
  40.             foreach (char bit in bits)
  41.             {
  42.                 PushBit(bit == '1');
  43.             }
  44.         }
  45.  
  46.         public void FlushBuffer()
  47.         {
  48.             for (int i = 7; i >= 0; i--)
  49.             {
  50.                 bool bit = (currBuf & (1 << i)) == 0;
  51.                 Console.Write(bit ? '0' : '1');
  52.             }
  53.             Console.WriteLine();
  54.             //Console.WriteLine(currBuf);
  55.             buffer[0] = currBuf;
  56.             writer.Write(currBuf);
  57.             currBuf = 0;
  58.             bufferCount = 0;
  59.         }
  60.  
  61.         public bool IsEmpty => bufferCount == 0;
  62.  
  63.         public int Size => bufferCount;
  64.     }
  65.     public class HuffmanNode
  66.     {
  67.         public double Key { get; set; }
  68.         public char Symbol { get; set; }
  69.         public HuffmanNode Left { get; set; }
  70.         public HuffmanNode Right { get; set; }
  71.         public bool IsTerminal { get; set; }
  72.     }
  73.     public class PriorityQueue/*<T> where T : IComparable<T>*/
  74.     {
  75.         private List<HuffmanNode> heap;
  76.  
  77.         public PriorityQueue()
  78.         {
  79.             heap = new List<HuffmanNode>();
  80.         }
  81.  
  82.         public PriorityQueue(IEnumerable<HuffmanNode> collection)
  83.         {
  84.             heap = new List<HuffmanNode>(collection);
  85.             BuildHeap();
  86.         }
  87.  
  88.         public void Enqueue(HuffmanNode item)
  89.         {
  90.             heap.Add(item);
  91.             HeapifyUp(heap.Count - 1);
  92.         }
  93.  
  94.         public HuffmanNode Dequeue()
  95.         {
  96.             if (IsEmpty())
  97.             {
  98.                 throw new InvalidOperationException("Priority queue is empty.");
  99.             }
  100.  
  101.             HuffmanNode minItem = heap[0];
  102.             int lastIndex = heap.Count - 1;
  103.             heap[0] = heap[lastIndex];
  104.             heap.RemoveAt(lastIndex);
  105.             HeapifyDown(0);
  106.  
  107.             return minItem;
  108.         }
  109.  
  110.         public HuffmanNode Peek()
  111.         {
  112.             if (IsEmpty())
  113.             {
  114.                 throw new InvalidOperationException("Priority queue is empty.");
  115.             }
  116.  
  117.             return heap[0];
  118.         }
  119.  
  120.         public bool IsEmpty()
  121.         {
  122.             return heap.Count == 0;
  123.         }
  124.  
  125.         private void HeapifyUp(int index)
  126.         {
  127.             int parentIndex = (index - 1) / 2;
  128.             while (index > 0 && heap[index].Key.CompareTo(heap[parentIndex].Key) < 0)
  129.             {
  130.                 Swap(index, parentIndex);
  131.                 index = parentIndex;
  132.                 parentIndex = (index - 1) / 2;
  133.             }
  134.         }
  135.  
  136.         private void HeapifyDown(int index)
  137.         {
  138.             int leftChildIndex = 2 * index + 1;
  139.             int rightChildIndex = 2 * index + 2;
  140.             int smallestIndex = index;
  141.  
  142.             if (leftChildIndex < heap.Count && heap[leftChildIndex].Key.CompareTo(heap[smallestIndex].Key) < 0)
  143.             {
  144.                 smallestIndex = leftChildIndex;
  145.             }
  146.  
  147.             if (rightChildIndex < heap.Count && heap[rightChildIndex].Key.CompareTo(heap[smallestIndex].Key) < 0)
  148.             {
  149.                 smallestIndex = rightChildIndex;
  150.             }
  151.  
  152.             if (smallestIndex != index)
  153.             {
  154.                 Swap(index, smallestIndex);
  155.                 HeapifyDown(smallestIndex);
  156.             }
  157.         }
  158.  
  159.         private void Swap(int i, int j)
  160.         {
  161.             HuffmanNode temp = heap[i];
  162.             heap[i] = heap[j];
  163.             heap[j] = temp;
  164.         }
  165.  
  166.         private void BuildHeap()
  167.         {
  168.             int lastNonLeafIndex = (heap.Count - 2) / 2;
  169.             for (int i = lastNonLeafIndex; i >= 0; i--)
  170.             {
  171.                 HeapifyDown(i);
  172.             }
  173.         }
  174.         public void PrintHeapTree()
  175.         {
  176.             PrintHeapTreeRecursive(0, 0);
  177.         }
  178.         private void PrintHeapTreeRecursive(int index, int level)
  179.         {
  180.             if (index < heap.Count)
  181.             {
  182.                 PrintHeapTreeRecursive(2 * index + 2, level + 1);
  183.  
  184.  
  185.                 for (int i = 0; i < level; i++)
  186.                 {
  187.                     Console.Write("    ");
  188.                 }
  189.  
  190.  
  191.                 Console.WriteLine(heap[index].Symbol);
  192.  
  193.                 PrintHeapTreeRecursive(2 * index + 1, level + 1);
  194.             }
  195.         }
  196.  
  197.     }
  198.     class Program
  199.     {
  200.         static HuffmanNode AddToTree(HuffmanNode item1, HuffmanNode item2)
  201.         {
  202.             HuffmanNode newItem = new HuffmanNode
  203.             {
  204.                 Key = item1.Key + item2.Key,
  205.                 Symbol = '\0',
  206.                 Left = item1,
  207.                 Right = item2,
  208.                 IsTerminal = false
  209.             };
  210.             return newItem;
  211.         }
  212.  
  213.         static void PrintTree(HuffmanNode tree)
  214.         {
  215.  
  216.             if (tree != null)
  217.             {
  218.                 Console.Write(tree.Key + " "+ tree.Symbol);
  219.                 Console.Write(" (");
  220.                 PrintTree(tree.Left);
  221.                 Console.Write(") ");
  222.                 Console.Write(" (");
  223.                 PrintTree(tree.Right);
  224.                 Console.Write(") ");
  225.             }
  226.             else
  227.             {
  228.                 Console.Write("null");
  229.             }
  230.         }
  231.  
  232.         static void RecordToTheDictionary(HuffmanNode tree, ref Dictionary<char, string> elements, string bits)
  233.         {
  234.             if (tree == null)
  235.             {
  236.                 return;
  237.             }
  238.  
  239.             if (tree.Left == null && tree.Right == null)
  240.             {
  241.                 elements[tree.Symbol] = bits;
  242.                 Console.WriteLine($"{bits} {tree.Symbol}");
  243.             }
  244.  
  245.             if (tree.Left != null)
  246.             {
  247.                 RecordToTheDictionary(tree.Left, ref elements, bits + "0");
  248.             }
  249.  
  250.             if (tree.Right != null)
  251.             {
  252.                 RecordToTheDictionary(tree.Right, ref elements,bits + "1");
  253.             }
  254.         }
  255.  
  256.         static bool UnZip(HuffmanNode tree, ref byte byteBuffer, ref int count,  StreamWriter writer,  ref BinaryReader binReader)
  257.         {
  258.             if (tree.Left == null || tree.Right == null)
  259.             {
  260.                 if (tree.Symbol == '$')
  261.                 {
  262.                     return false;
  263.                 }
  264.                 else
  265.                 {
  266.                     writer.Write(tree.Symbol);
  267.                     Console.Write(tree.Symbol);
  268.                     return true;
  269.                 }
  270.             }
  271.  
  272.             if (count == -1)
  273.             {
  274.                 byte value;
  275.  
  276.                 try
  277.                 {
  278.                     value = binReader.ReadByte();
  279.                    
  280.                 }
  281.                 catch (EndOfStreamException)
  282.                 {
  283.                     return false;
  284.                 }
  285.  
  286.                 byteBuffer = value;
  287.                 count = 7;
  288.  
  289.  
  290.                 //byte value = byteBuffer[0];
  291.                 //Array.Copy(byteBuffer, 1, byteBuffer, 0, byteBuffer.Length - 1);
  292.                 //byteBuffer[byteBuffer.Length - 1] = 0;
  293.                 //count = 7;
  294.                 //for (int i = 0; i < 8; i++)
  295.                 //{
  296.                 //    writer.Write((value & (1 << (7 - i))) != 0 ? '1' : '0');
  297.                 //}
  298.             }
  299.             //bool bitValue = (byteBuffer & (1 << count)) != 0;
  300.            
  301.             if ((byteBuffer & (1 << count)) == 0)
  302.             {
  303.                 count--;
  304.                 return UnZip(tree.Left, ref byteBuffer, ref count,  writer, ref binReader);
  305.             }
  306.             else
  307.             {
  308.                 count--;
  309.                 return UnZip(tree.Right, ref byteBuffer, ref count, writer,ref  binReader);
  310.             }
  311.         }
  312.  
  313.         static void Main(string[] args)
  314.         {
  315.             List<char> symbols = new List<char>();
  316.             List<double> frequencies = new List<double>();
  317.             List<HuffmanNode> items = new List<HuffmanNode>();
  318.             symbols.Add('$');
  319.             frequencies.Add(0);
  320.             HuffmanNode newNode = new HuffmanNode
  321.             {
  322.                 Key = 0,
  323.                 Symbol = '$',
  324.                 Left = null,
  325.                 Right = null,
  326.                 IsTerminal = true
  327.             };
  328.             items.Add(newNode);
  329.  
  330.             using (StreamReader reader = new StreamReader("freq.dat", Encoding.Unicode))
  331.             {
  332.                 char[] symbol = new char[2];
  333.                 double frequency= 0;
  334.  
  335.                 while (reader.Peek() >= 0)
  336.                 {
  337.                     //int count = 0;
  338.                     reader.Read(symbol, 0, 1);
  339.                     symbols.Add(symbol[0]);
  340.                     reader.Read(symbol, 1, 1); // Read space
  341.                     string line = reader.ReadLine();
  342.                     frequency = double.Parse(line);
  343.                     frequencies.Add(frequency);
  344.                     HuffmanNode item = new HuffmanNode
  345.                     {
  346.                         Key = frequency,
  347.                         Symbol = symbol[0],
  348.                         Left = null,
  349.                         Right = null,
  350.                         IsTerminal = true
  351.                     };
  352.                     items.Add(item);
  353.                     Console.WriteLine($"{symbol[0]} {frequency}");
  354.                    
  355.                 }
  356.             }
  357.  
  358.             HuffmanNode newItem = null;
  359.             while (items.Count > 1)
  360.             {
  361.                 items = items.OrderByDescending(x => x.Key).ToList();
  362.                 newItem = AddToTree(items.Last(), items[items.Count - 2]);
  363.                 items.RemoveAt(items.Count - 1);
  364.                 items.RemoveAt(items.Count - 1);
  365.                 items.Add(newItem);
  366.             }
  367.  
  368.             Dictionary<char, string> elements = new Dictionary<char, string>();
  369.             string bits = "";
  370.             PrintTree(newItem);
  371.             Console.WriteLine("------------------------------------");
  372.  
  373.  
  374.             RecordToTheDictionary(newItem, ref elements, bits);
  375.  
  376.             foreach (var element in elements)
  377.             {
  378.                 Console.WriteLine($"{element.Key}\t{element.Value}");
  379.             }
  380.            
  381.  
  382.             using (StreamReader textReader = new StreamReader("input.dat", Encoding.Unicode))
  383.             {
  384.                 BinaryWriter binaryWriter = new BinaryWriter(File.Open("output.arc", FileMode.Create));
  385.                 BitBuffer buffer = new BitBuffer(binaryWriter);
  386.                 char[] item = new char[1];
  387.                 while (textReader.Peek()!=-1)
  388.                 {
  389.                     string encodedBits;
  390.                     textReader.Read(item,0,1);
  391.                     try
  392.                     {
  393.                         encodedBits = elements[item[0]];
  394.                        
  395.                     }
  396.                     catch (KeyNotFoundException ex)
  397.                     {
  398.                        
  399.                        continue;
  400.                     }
  401.                     buffer.Convert(encodedBits);
  402.                 }
  403.  
  404.                 if (!buffer.IsEmpty)
  405.                 {
  406.                     buffer.Convert(elements['$']);
  407.                 }
  408.  
  409.                 while (!buffer.IsEmpty)
  410.                 {
  411.                     buffer.PushBit(true);
  412.                 }
  413.                 binaryWriter.Close();
  414.             }
  415.             //using (BinaryWriter binaryWriter = new BinaryWriter(File.Open("output.arc", FileMode.Create)))
  416.  
  417.                
  418.  
  419.             using (StreamWriter textWriter = new StreamWriter("text.dat"))
  420.             {
  421.                 BinaryReader binaryReader = new BinaryReader(File.Open("output.arc", FileMode.Open));
  422.                 //BitBuffer buffer = new BitBuffer();
  423.  
  424.  
  425.  
  426.                 byte byteBuffer = new byte();
  427.                 int count = -1;
  428.  
  429.                 while (UnZip(newItem, ref byteBuffer, ref count, textWriter,  ref binaryReader))
  430.                 {
  431.                 }
  432.                 binaryReader.Close();
  433.             }
  434.         }
  435.     }
  436. }
Advertisement
Add Comment
Please, Sign In to add comment