75 lines
2 KiB
Text
75 lines
2 KiB
Text
$ include "seed7_05.s7i";
|
|
|
|
const func string: lzwCompress (in string: uncompressed) is func
|
|
result
|
|
var string: compressed is "";
|
|
local
|
|
var char: ch is ' ';
|
|
var hash [string] char: mydict is (hash [string] char).value;
|
|
var string: buffer is "";
|
|
var string: xstr is "";
|
|
begin
|
|
for ch range chr(0) to chr(255) do
|
|
mydict @:= [str(ch)] ch;
|
|
end for;
|
|
for ch range uncompressed do
|
|
xstr := buffer & str(ch);
|
|
if xstr in mydict then
|
|
buffer &:= str(ch)
|
|
else
|
|
compressed &:= str(mydict[buffer]);
|
|
mydict @:= [xstr] chr(length(mydict));
|
|
buffer := str(ch);
|
|
end if;
|
|
end for;
|
|
if buffer <> "" then
|
|
compressed &:= str(mydict[buffer]);
|
|
end if;
|
|
end func;
|
|
|
|
const func string: lzwDecompress (in string: compressed) is func
|
|
result
|
|
var string: uncompressed is "";
|
|
local
|
|
var char: ch is ' ';
|
|
var hash [char] string: mydict is (hash [char] string).value;
|
|
var string: buffer is "";
|
|
var string: current is "";
|
|
var string: chain is "";
|
|
begin
|
|
for ch range chr(0) to chr(255) do
|
|
mydict @:= [ch] str(ch);
|
|
end for;
|
|
for ch range compressed do
|
|
if buffer = "" then
|
|
buffer := mydict[ch];
|
|
uncompressed &:= buffer;
|
|
elsif ch <= chr(255) then
|
|
current := mydict[ch];
|
|
uncompressed &:= current;
|
|
chain := buffer & current;
|
|
mydict @:= [chr(length(mydict))] chain;
|
|
buffer := current;
|
|
else
|
|
if ch in mydict then
|
|
chain := mydict[ch];
|
|
else
|
|
chain := buffer & str(buffer[1]);
|
|
end if;
|
|
uncompressed &:= chain;
|
|
mydict @:= [chr(length(mydict))] buffer & str(chain[1]);
|
|
buffer := chain;
|
|
end if;
|
|
end for;
|
|
end func;
|
|
|
|
const proc: main is func
|
|
local
|
|
var string: compressed is "";
|
|
var string: uncompressed is "";
|
|
begin
|
|
compressed := lzwCompress("TOBEORNOTTOBEORTOBEORNOT");
|
|
writeln(literal(compressed));
|
|
uncompressed := lzwDecompress(compressed);
|
|
writeln(uncompressed);
|
|
end func;
|