Advertisement
Vladislav8653

Haffmun

Jun 12th, 2023
307
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 3.87 KB | None | 0 0
  1. program HuffmanCode;
  2. uses
  3.     System.SysUtils;
  4.  
  5. type
  6.   PNode = ^TNode;
  7.   TNode = record
  8.     ch: Char;
  9.     freq: Integer;
  10.     left, right: PNode;
  11.   end;
  12.  
  13.   TPriorityQueue = record
  14.     nodes: array of PNode;
  15.     count: Integer;
  16.   end;
  17.  
  18.   TCharFrequency = record
  19.     ch: Char;
  20.     freq: Integer;
  21.   end;
  22.  
  23.   THuffmanCode = record
  24.     codeMap: array [Char] of string;
  25.   end;
  26.  
  27. procedure InitializePriorityQueue(var pq: TPriorityQueue);
  28. begin
  29.   SetLength(pq.nodes, 256);
  30.   pq.count := 0;
  31. end;
  32.  
  33. procedure Enqueue(var pq: TPriorityQueue; node: PNode);
  34. var
  35.   i: Integer;
  36. begin
  37.   i := pq.count;
  38.   while (i > 0) and (node.freq < pq.nodes[i - 1].freq) do
  39.   begin
  40.     pq.nodes[i] := pq.nodes[i - 1];
  41.     Dec(i);
  42.   end;
  43.   pq.nodes[i] := node;
  44.   Inc(pq.count);
  45. end;
  46.  
  47. function Dequeue(var pq: TPriorityQueue): PNode;
  48. begin
  49.   if pq.count > 0 then
  50.   begin
  51.     Result := pq.nodes[0];
  52.     Dec(pq.count);
  53.     Move(pq.nodes[1], pq.nodes[0], pq.count * SizeOf(PNode));
  54.   end
  55.   else
  56.     Result := nil;
  57. end;
  58.  
  59. procedure BuildHuffmanTree(const text: string; var root: PNode);
  60. var
  61.   freq: array [Char] of Integer;
  62.   ch: Char;
  63.   i: Integer;
  64.   node: PNode;
  65.   pq: TPriorityQueue;
  66. begin
  67.   for ch := Low(Char) to High(Char) do
  68.     freq[ch] := 0;
  69.  
  70.   for i := 1 to Length(text) do
  71.     Inc(freq[text[i]]);
  72.  
  73.   InitializePriorityQueue(pq);
  74.  
  75.   for ch := Low(Char) to High(Char) do
  76.   begin
  77.     if freq[ch] > 0 then
  78.     begin
  79.       New(node);
  80.       node.ch := ch;
  81.       node.freq := freq[ch];
  82.       node.left := nil;
  83.       node.right := nil;
  84.       Enqueue(pq, node);
  85.     end;
  86.   end;
  87.  
  88.   while pq.count > 1 do
  89.   begin
  90.     New(node);
  91.     node.left := Dequeue(pq);
  92.     node.right := Dequeue(pq);
  93.     node.freq := node.left.freq + node.right.freq;
  94.     Enqueue(pq, node);
  95.   end;
  96.  
  97.   root := Dequeue(pq);
  98. end;
  99.  
  100. procedure EncodeData(node: PNode; const str: string; var huffmanCode: THuffmanCode);
  101. begin
  102.   if node = nil then
  103.     Exit;
  104.  
  105.   if (node^.left = nil) and (node^.right = nil) then
  106.     huffmanCode.codeMap[node^.ch] := str
  107.   else
  108.   begin
  109.     EncodeData(node^.left, str + '0', huffmanCode);
  110.     EncodeData(node^.right, str + '1', huffmanCode);
  111.   end;
  112. end;
  113.  
  114. procedure DecodeData(node: PNode; var index: Integer; const sb: string);
  115. begin
  116.   if node = nil then
  117.     Exit;
  118.  
  119.   if (node^.left = nil) and (node^.right = nil) then
  120.   begin
  121.     Write(node^.ch);
  122.     Exit;
  123.   end;
  124.  
  125.   Inc(index);
  126.   if sb[index] = '0' then
  127.     DecodeData(node^.left, index, sb)
  128.   else
  129.     DecodeData(node^.right, index, sb);
  130. end;
  131.  
  132. procedure FreeTree(node: PNode);
  133. begin
  134.   if node = nil then
  135.     Exit;
  136.  
  137.   FreeTree(node^.left);
  138.   FreeTree(node^.right);
  139.   Dispose(node);
  140. end;
  141.  
  142. procedure CreateHuffmanTree(const text: string);
  143. var
  144.   root: PNode;
  145.   huffmanCode: THuffmanCode;
  146.   sb: TStringBuilder;
  147.   i, index: Integer;
  148.   ch: Char;
  149. begin
  150.   if text = '' then
  151.     Exit;
  152.  
  153.   BuildHuffmanTree(text, root);
  154.  
  155.   FillChar(huffmanCode, SizeOf(huffmanCode), 0);
  156.   EncodeData(root, '', huffmanCode);
  157.  
  158.   WriteLn('Huffman Codes of the characters are:');
  159.   for ch := Low(Char) to High(Char) do
  160.   begin
  161.     if huffmanCode.codeMap[ch] <> '' then
  162.       WriteLn(ch, ': ', huffmanCode.codeMap[ch]);
  163.   end;
  164.  
  165.   WriteLn('The initial string is: ', text);
  166.  
  167.   sb := TStringBuilder.Create;
  168.   for i := 1 to Length(text) do
  169.     sb.Append(huffmanCode.codeMap[text[i]]);
  170.  
  171.   WriteLn('The encoded string is: ', sb.ToString);
  172.  
  173.   Write('The decoded string is: ');
  174.   if (root^.left = nil) and (root^.right = nil) then
  175.   begin
  176.     while root^.freq > 0 do
  177.     begin
  178.       Write(root^.ch);
  179.       Dec(root^.freq);
  180.     end;
  181.   end
  182.   else
  183.   begin
  184.     index := 0;
  185.     while index < sb.Length do
  186.       DecodeData(root, index, sb.ToString);
  187.   end;
  188.  
  189.   FreeTree(root);
  190.   sb.Free;
  191. end;
  192.  
  193. var
  194.   text: string;
  195. begin
  196.   text := 'абабвгвгдеде';
  197.   CreateHuffmanTree(text);
  198.   readln;
  199. end.
  200.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement