Advertisement
Guest User

Untitled

a guest
Jul 22nd, 2017
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Delphi 4.24 KB | None | 0 0
  1. unit main;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  7.   Dialogs, StdCtrls;
  8.  
  9. type
  10.   TForm1 = class(TForm)
  11.     Button1: TButton;
  12.     procedure Button1Click(Sender: TObject);
  13.   private
  14.     { Private declarations }
  15.   public
  16.     { Public declarations }
  17.   end;
  18.  
  19. type
  20. PPhrase=^TPhrase;
  21. TPhrase=array of char;
  22.  
  23. type
  24. PLZWTABLE=^TLZWTABLE;
  25. TLZWTABLE=array [0..4095] of TPhrase;
  26.  
  27. var
  28.   Form1: TForm1;
  29.   lzw_table: TLZWTable;
  30.   tablecurrentlimit: dword=256;
  31.   msg: string='TOBEORNOTTOBETOBEORNOTTOBE';
  32.   cur: dword=0;
  33.   phrase, tempphrase: TPhrase;
  34.   outmsg: array [0..4095] of char;
  35.   currbite: dword=0;
  36.   currbyte: byte=0;
  37.   halfflag: bool=false;
  38.   Data: byte;
  39.   bitcount: dword=0;
  40.  
  41. implementation
  42.  
  43. {$R *.dfm}
  44.  
  45. function GetMaxBit(Value: dword): dword; assembler;
  46. asm
  47.  push ECX
  48.  push EDX
  49.  mov EAX, Value
  50.  mov ECX, 32
  51.  xor EDX, EDX
  52.  @testbit:
  53.   shl EAX, 1
  54.   jnc @NextBit
  55.    mov ECX, 1
  56.   @NextBit:
  57.  inc EDX
  58.  dec ECX
  59.  jnz @testbit
  60.  mov EAX, EDX
  61.  mov EDX, 32
  62.  sub EDX, EAX
  63.  mov EAX, EDX
  64.  inc EAX
  65.  pop EDX
  66.  pop ECX
  67. end;
  68.  
  69. function GetChar(): char;
  70. begin
  71.  result:=msg[cur+1];
  72.  inc(cur);
  73. end;
  74.  
  75. procedure InitLZWTable(lzw_table: PLZWTABLE);
  76. var i: dword;
  77. begin
  78.  for i:=0 to 255 do
  79.  begin
  80.   SetLength(lzw_table[i], 1);
  81.   lzw_table[i][0]:=char(i);
  82.  end;
  83. end;
  84.  
  85. function IsPhraseExistsInTable(phrase: PPhrase; lzw_table: PLZWTable): dword;
  86. var lt, lp, i, c: dword; cmpf: bool;
  87. begin
  88.  result:=dword(-1);
  89.  lp:=length(phrase^);
  90.  if (lp=0) then exit;
  91.  for i:=0 to 4095 do // перебор цепочек в таблице
  92.  begin
  93.   lt:=length(lzw_table[i]);
  94.   if (lt=lp) then  // посимвольное сравнение при условии совпадения длин
  95.   begin
  96.    cmpf:=true;
  97.    for c:=0 to lt-1 do
  98.    begin
  99.     if phrase^[c]<>lzw_table[i][c] then
  100.     begin
  101.      cmpf:=false;
  102.      break;
  103.     end;
  104.    end;
  105.    if cmpf then
  106.    begin
  107.     result:=i;
  108.     break;
  109.    end;
  110.   end;
  111.  end;
  112. end;
  113.  
  114. procedure AddSymToPhrase(buf: PPhrase; sym: char);
  115. var l: dword;
  116. begin
  117.  l:=length(buf^);
  118.  inc(l);
  119.  SetLength(buf^, l);
  120.  buf^[l-1]:=sym;
  121. end;
  122.  
  123. procedure PutCode2Out(Code: dword; NBits: dword);
  124. var b, i: dword;
  125. begin
  126.  data:=0;
  127.  for i:=0 to nbits-1 do
  128.  begin
  129.   b:=(code shr nbits-currbite) and 1;
  130.   data:=(data shl 1) or b;
  131.   inc(currbite);
  132.   if currbite=8 then
  133.   begin
  134.    outmsg[currbyte]:=char(data);
  135.    inc(currbyte);
  136.    data:=0;
  137.    currbite:=0;
  138.   end;
  139.  end;
  140. end;
  141.  
  142. procedure SkipPhrase(Phrase: PPhrase);
  143. var l: dword;
  144. begin
  145.  l:=length(Phrase^);
  146.  Phrase^[0]:=Phrase^[l-1];
  147.  SetLength(Phrase^, 1);
  148. end;
  149.  
  150. procedure AddPhrase2Table(lzw_table: PLZWTable; Phrase: PPhrase);
  151. var l, i: dword;
  152. begin
  153.  if tablecurrentlimit=4095 then
  154.  begin
  155.   // table overload
  156.  end;
  157.  inc(tablecurrentlimit);
  158.  l:=length(Phrase^);
  159.  SetLength(lzw_table^[tablecurrentlimit-1], l);
  160.  for i:=0 to l-1 do lzw_table^[tablecurrentlimit-1][i]:=Phrase^[i];
  161. end;
  162.  
  163. procedure TForm1.Button1Click(Sender: TObject);
  164. var i, l, Code, LastCode: dword; sym: char;
  165. begin
  166.  InitLZWTable(@lzw_table);  // начальная инициализация таблицы цепочек 8 битными цепочками
  167.  l:=length(msg);
  168.  for i:=0 to l do
  169.  begin
  170.   sym:=GetChar();
  171.   AddSymToPhrase(@phrase, sym); // добавляем K к [.c.]
  172.   if IsPhraseExistsInTable(@phrase, @lzw_table)=dword(-1) then // проверка водит ли [.c.]K в таблицу цепочек
  173.   begin
  174.    tempphrase:=phrase;
  175.    SetLength(tempphrase, length(tempphrase)-1); // обрезаем последний символ (оставить только [.c]!!!)
  176.    Code:=IsPhraseExistsInTable(@tempphrase, @lzw_table); // получить код цепочки (без последнего символа) в таблице, так как [.c.] заведомо входит в теблицу
  177.    PutCode2Out(Code, GetMaxBit(tablecurrentlimit)); // определение длинны кода и вывод кода произвольной длинны в буффер
  178.    AddPhrase2Table(@lzw_table, @phrase); // добавить цепочку в таблицу цепочек
  179.    SkipPhrase(@phrase); // оставить в цепочке последний символ
  180.   end;
  181.  end;
  182. end;
  183.  
  184. end.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement