Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- namespace Архиватор
- {
- class BitBuffer
- {
- private const int BufferSize = 8;
- private byte[] buffer = new byte[1];
- private byte currBuf = new byte();
- private int bufferCount = 0;
- BinaryWriter writer = null;
- public BitBuffer(BinaryWriter writer)
- {
- this.writer = writer;
- }
- public void PushBit(bool bit)
- {
- currBuf <<= 1;
- if (bit)
- {
- currBuf |= 1;
- }
- bufferCount++;
- if (bufferCount >= BufferSize)
- {
- FlushBuffer();
- }
- }
- public void Convert(string bits)
- {
- foreach (char bit in bits)
- {
- PushBit(bit == '1');
- }
- }
- public void FlushBuffer()
- {
- for (int i = 7; i >= 0; i--)
- {
- bool bit = (currBuf & (1 << i)) == 0;
- Console.Write(bit ? '0' : '1');
- }
- Console.WriteLine();
- //Console.WriteLine(currBuf);
- buffer[0] = currBuf;
- writer.Write(currBuf);
- currBuf = 0;
- bufferCount = 0;
- }
- public bool IsEmpty => bufferCount == 0;
- public int Size => bufferCount;
- }
- public class HuffmanNode
- {
- public double Key { get; set; }
- public char Symbol { get; set; }
- public HuffmanNode Left { get; set; }
- public HuffmanNode Right { get; set; }
- public bool IsTerminal { get; set; }
- }
- public class PriorityQueue/*<T> where T : IComparable<T>*/
- {
- private List<HuffmanNode> heap;
- public PriorityQueue()
- {
- heap = new List<HuffmanNode>();
- }
- public PriorityQueue(IEnumerable<HuffmanNode> collection)
- {
- heap = new List<HuffmanNode>(collection);
- BuildHeap();
- }
- public void Enqueue(HuffmanNode item)
- {
- heap.Add(item);
- HeapifyUp(heap.Count - 1);
- }
- public HuffmanNode Dequeue()
- {
- if (IsEmpty())
- {
- throw new InvalidOperationException("Priority queue is empty.");
- }
- HuffmanNode minItem = heap[0];
- int lastIndex = heap.Count - 1;
- heap[0] = heap[lastIndex];
- heap.RemoveAt(lastIndex);
- HeapifyDown(0);
- return minItem;
- }
- public HuffmanNode Peek()
- {
- if (IsEmpty())
- {
- throw new InvalidOperationException("Priority queue is empty.");
- }
- return heap[0];
- }
- public bool IsEmpty()
- {
- return heap.Count == 0;
- }
- private void HeapifyUp(int index)
- {
- int parentIndex = (index - 1) / 2;
- while (index > 0 && heap[index].Key.CompareTo(heap[parentIndex].Key) < 0)
- {
- Swap(index, parentIndex);
- index = parentIndex;
- parentIndex = (index - 1) / 2;
- }
- }
- private void HeapifyDown(int index)
- {
- int leftChildIndex = 2 * index + 1;
- int rightChildIndex = 2 * index + 2;
- int smallestIndex = index;
- if (leftChildIndex < heap.Count && heap[leftChildIndex].Key.CompareTo(heap[smallestIndex].Key) < 0)
- {
- smallestIndex = leftChildIndex;
- }
- if (rightChildIndex < heap.Count && heap[rightChildIndex].Key.CompareTo(heap[smallestIndex].Key) < 0)
- {
- smallestIndex = rightChildIndex;
- }
- if (smallestIndex != index)
- {
- Swap(index, smallestIndex);
- HeapifyDown(smallestIndex);
- }
- }
- private void Swap(int i, int j)
- {
- HuffmanNode temp = heap[i];
- heap[i] = heap[j];
- heap[j] = temp;
- }
- private void BuildHeap()
- {
- int lastNonLeafIndex = (heap.Count - 2) / 2;
- for (int i = lastNonLeafIndex; i >= 0; i--)
- {
- HeapifyDown(i);
- }
- }
- public void PrintHeapTree()
- {
- PrintHeapTreeRecursive(0, 0);
- }
- private void PrintHeapTreeRecursive(int index, int level)
- {
- if (index < heap.Count)
- {
- PrintHeapTreeRecursive(2 * index + 2, level + 1);
- for (int i = 0; i < level; i++)
- {
- Console.Write(" ");
- }
- Console.WriteLine(heap[index].Symbol);
- PrintHeapTreeRecursive(2 * index + 1, level + 1);
- }
- }
- }
- class Program
- {
- static HuffmanNode AddToTree(HuffmanNode item1, HuffmanNode item2)
- {
- HuffmanNode newItem = new HuffmanNode
- {
- Key = item1.Key + item2.Key,
- Symbol = '\0',
- Left = item1,
- Right = item2,
- IsTerminal = false
- };
- return newItem;
- }
- static void PrintTree(HuffmanNode tree)
- {
- if (tree != null)
- {
- Console.Write(tree.Key + " "+ tree.Symbol);
- Console.Write(" (");
- PrintTree(tree.Left);
- Console.Write(") ");
- Console.Write(" (");
- PrintTree(tree.Right);
- Console.Write(") ");
- }
- else
- {
- Console.Write("null");
- }
- }
- static void RecordToTheDictionary(HuffmanNode tree, ref Dictionary<char, string> elements, string bits)
- {
- if (tree == null)
- {
- return;
- }
- if (tree.Left == null && tree.Right == null)
- {
- elements[tree.Symbol] = bits;
- Console.WriteLine($"{bits} {tree.Symbol}");
- }
- if (tree.Left != null)
- {
- RecordToTheDictionary(tree.Left, ref elements, bits + "0");
- }
- if (tree.Right != null)
- {
- RecordToTheDictionary(tree.Right, ref elements,bits + "1");
- }
- }
- static bool UnZip(HuffmanNode tree, ref byte byteBuffer, ref int count, StreamWriter writer, ref BinaryReader binReader)
- {
- if (tree.Left == null || tree.Right == null)
- {
- if (tree.Symbol == '$')
- {
- return false;
- }
- else
- {
- writer.Write(tree.Symbol);
- Console.Write(tree.Symbol);
- return true;
- }
- }
- if (count == -1)
- {
- byte value;
- try
- {
- value = binReader.ReadByte();
- }
- catch (EndOfStreamException)
- {
- return false;
- }
- byteBuffer = value;
- count = 7;
- //byte value = byteBuffer[0];
- //Array.Copy(byteBuffer, 1, byteBuffer, 0, byteBuffer.Length - 1);
- //byteBuffer[byteBuffer.Length - 1] = 0;
- //count = 7;
- //for (int i = 0; i < 8; i++)
- //{
- // writer.Write((value & (1 << (7 - i))) != 0 ? '1' : '0');
- //}
- }
- //bool bitValue = (byteBuffer & (1 << count)) != 0;
- if ((byteBuffer & (1 << count)) == 0)
- {
- count--;
- return UnZip(tree.Left, ref byteBuffer, ref count, writer, ref binReader);
- }
- else
- {
- count--;
- return UnZip(tree.Right, ref byteBuffer, ref count, writer,ref binReader);
- }
- }
- static void Main(string[] args)
- {
- List<char> symbols = new List<char>();
- List<double> frequencies = new List<double>();
- List<HuffmanNode> items = new List<HuffmanNode>();
- symbols.Add('$');
- frequencies.Add(0);
- HuffmanNode newNode = new HuffmanNode
- {
- Key = 0,
- Symbol = '$',
- Left = null,
- Right = null,
- IsTerminal = true
- };
- items.Add(newNode);
- using (StreamReader reader = new StreamReader("freq.dat", Encoding.Unicode))
- {
- char[] symbol = new char[2];
- double frequency= 0;
- while (reader.Peek() >= 0)
- {
- //int count = 0;
- reader.Read(symbol, 0, 1);
- symbols.Add(symbol[0]);
- reader.Read(symbol, 1, 1); // Read space
- string line = reader.ReadLine();
- frequency = double.Parse(line);
- frequencies.Add(frequency);
- HuffmanNode item = new HuffmanNode
- {
- Key = frequency,
- Symbol = symbol[0],
- Left = null,
- Right = null,
- IsTerminal = true
- };
- items.Add(item);
- Console.WriteLine($"{symbol[0]} {frequency}");
- }
- }
- HuffmanNode newItem = null;
- while (items.Count > 1)
- {
- items = items.OrderByDescending(x => x.Key).ToList();
- newItem = AddToTree(items.Last(), items[items.Count - 2]);
- items.RemoveAt(items.Count - 1);
- items.RemoveAt(items.Count - 1);
- items.Add(newItem);
- }
- Dictionary<char, string> elements = new Dictionary<char, string>();
- string bits = "";
- PrintTree(newItem);
- Console.WriteLine("------------------------------------");
- RecordToTheDictionary(newItem, ref elements, bits);
- foreach (var element in elements)
- {
- Console.WriteLine($"{element.Key}\t{element.Value}");
- }
- using (StreamReader textReader = new StreamReader("input.dat", Encoding.Unicode))
- {
- BinaryWriter binaryWriter = new BinaryWriter(File.Open("output.arc", FileMode.Create));
- BitBuffer buffer = new BitBuffer(binaryWriter);
- char[] item = new char[1];
- while (textReader.Peek()!=-1)
- {
- string encodedBits;
- textReader.Read(item,0,1);
- try
- {
- encodedBits = elements[item[0]];
- }
- catch (KeyNotFoundException ex)
- {
- continue;
- }
- buffer.Convert(encodedBits);
- }
- if (!buffer.IsEmpty)
- {
- buffer.Convert(elements['$']);
- }
- while (!buffer.IsEmpty)
- {
- buffer.PushBit(true);
- }
- binaryWriter.Close();
- }
- //using (BinaryWriter binaryWriter = new BinaryWriter(File.Open("output.arc", FileMode.Create)))
- using (StreamWriter textWriter = new StreamWriter("text.dat"))
- {
- BinaryReader binaryReader = new BinaryReader(File.Open("output.arc", FileMode.Open));
- //BitBuffer buffer = new BitBuffer();
- byte byteBuffer = new byte();
- int count = -1;
- while (UnZip(newItem, ref byteBuffer, ref count, textWriter, ref binaryReader))
- {
- }
- binaryReader.Close();
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment