2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,3 +1,4 @@
|
|||
The Lempel-Ziv-Welch (LZW) algorithm provides lossless data compression.
|
||||
You can read a complete description of it in the [[wp:Lempel-Ziv-Welch|Wikipedia article]] on the subject.
|
||||
It was patented, but it entered the public domain in 2004.
|
||||
The Lempel-Ziv-Welch (LZW) algorithm provides loss-less data compression.
|
||||
|
||||
You can read a complete description of it in the [[wp:Lempel-Ziv-Welch|Wikipedia article]] on the subject. It was patented, but it entered the public domain in 2004.
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -1,45 +1,36 @@
|
|||
defmodule LZW do
|
||||
def encode(str), do: encode(to_char_list(str), init, 256, [])
|
||||
@encode_map Enum.into(0..255, Map.new, &{[&1],&1})
|
||||
@decode_map Enum.into(0..255, Map.new, &{&1,[&1]})
|
||||
|
||||
defp encode([h], d, _, out), do: Enum.reverse([Dict.get(d, [h]) | out])
|
||||
def encode(str), do: encode(to_char_list(str), @encode_map, 256, [])
|
||||
|
||||
defp encode([h], d, _, out), do: Enum.reverse([d[[h]] | out])
|
||||
defp encode([h|t], d, free, out) do
|
||||
val = Dict.get(d, [h])
|
||||
val = d[[h]]
|
||||
find_match(t, [h], val, d, free, out)
|
||||
end
|
||||
|
||||
defp find_match([h|t], l, lastval, d, free, out) do
|
||||
case Dict.fetch(d, [h|l]) do
|
||||
case Map.fetch(d, [h|l]) do
|
||||
{:ok, val} -> find_match(t, [h|l], val, d, free, out)
|
||||
:error ->
|
||||
d1 = Dict.put(d, [h|l], free)
|
||||
encode([h|t], d1, free+1, [lastval | out])
|
||||
:error -> d1 = Map.put(d, [h|l], free)
|
||||
encode([h|t], d1, free+1, [lastval | out])
|
||||
end
|
||||
end
|
||||
defp find_match([], _, lastval, _, _, out), do: Enum.reverse([lastval | out])
|
||||
|
||||
defp init, do: init(255, Map.new)
|
||||
|
||||
defp init(0, d), do: d
|
||||
defp init(n, d), do: init(n-1, Dict.put(d,[n],n))
|
||||
|
||||
def decode([h|t]) do
|
||||
d = init1(Map.new)
|
||||
val = Dict.get(d, h)
|
||||
decode(t, val, 256, d, val)
|
||||
val = @decode_map[h]
|
||||
decode(t, val, 256, @decode_map, val)
|
||||
end
|
||||
|
||||
defp decode([], _, _, _, l), do: Enum.reverse(l) |> to_string
|
||||
defp decode([h|t], old, free, d, l) do
|
||||
val = Dict.get(d, h)
|
||||
val = d[h]
|
||||
add = [List.last(val) | old]
|
||||
d1 = Dict.put(d, free, add)
|
||||
d1 = Map.put(d, free, add)
|
||||
decode(t, val, free+1, d1, val++l)
|
||||
end
|
||||
|
||||
defp init1(d), do: init1(255, d)
|
||||
|
||||
defp init1(0, d), do: d
|
||||
defp init1(n, d), do: init1(n-1, Dict.put(d, n, [n]))
|
||||
end
|
||||
|
||||
str = "TOBEORNOTTOBEORTOBEORNOT"
|
||||
|
|
|
|||
49
Task/LZW-compression/Lua/lzw-compression.lua
Normal file
49
Task/LZW-compression/Lua/lzw-compression.lua
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
local function compress(uncompressed) -- string
|
||||
local dictionary, result, dictSize, w, c = {}, {}, 255, ""
|
||||
for i = 0, 255 do
|
||||
dictionary[string.char(i)] = i
|
||||
end
|
||||
for i = 1, #uncompressed do
|
||||
c = string.sub(uncompressed, i, i)
|
||||
if dictionary[w .. c] then
|
||||
w = w .. c
|
||||
else
|
||||
table.insert(result, dictionary[w])
|
||||
dictSize = dictSize + 1
|
||||
dictionary[w .. c] = dictSize
|
||||
w = c
|
||||
end
|
||||
end
|
||||
if w ~= "" then
|
||||
table.insert(result, dictionary[w])
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local function decompress(compressed) -- table
|
||||
local dictionary, dictSize, entry, result, w, k = {}, 255, "", "", ""
|
||||
for i = 0, 255 do
|
||||
dictionary[i] = string.char(i)
|
||||
end
|
||||
for i = 1, #compressed do
|
||||
k = compressed[i]
|
||||
if dictionary[k] then
|
||||
entry = dictionary[k]
|
||||
elseif k == dictSize then
|
||||
entry = w .. string.sub(w, 1, 1)
|
||||
else
|
||||
return nil, i
|
||||
end
|
||||
result = result .. entry
|
||||
dictionary[dictSize] = w .. string.sub(entry, 1, 1)
|
||||
dictSize = dictSize + 1
|
||||
w = entry
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
local example = "TOBEORNOTTOBEORTOBEORNOT"
|
||||
local com = compress(example)
|
||||
local dec = decompress(com)
|
||||
print(table.concat(com, ", "))
|
||||
print(dec)
|
||||
|
|
@ -3,8 +3,8 @@ def compress(uncompressed):
|
|||
|
||||
# Build the dictionary.
|
||||
dict_size = 256
|
||||
dictionary = dict((chr(i), chr(i)) for i in xrange(dict_size))
|
||||
# in Python 3: dictionary = {chr(i): chr(i) for i in range(dict_size)}
|
||||
dictionary = dict((chr(i), i) for i in xrange(dict_size))
|
||||
# in Python 3: dictionary = {chr(i): i for i in range(dict_size)}
|
||||
|
||||
w = ""
|
||||
result = []
|
||||
|
|
|
|||
|
|
@ -1,32 +1,31 @@
|
|||
/*REXX pgm compresses text using LZW (Lempel-Ziv-Welch), and reconstitutes it.*/
|
||||
parse arg x /*get an optional argument from the CL.*/
|
||||
if x=='' then x='"There is nothing permanent except change." ─── Heraclitus [540-475 BC]'
|
||||
say 'original text=' x
|
||||
cypher=LZWc(x) /*compress text using the LZW algorithm*/
|
||||
say 'reconstituted=' LZWd(cypher)
|
||||
say ' LZW integers=' cypher /*also display the LZW integers used. */
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
LZWc: procedure; parse arg y,,w $ @.; #=256 /*the LZW compress algorithm.*/
|
||||
do j=0 for 256; _=d2c(j); @._=j; end /*j*/
|
||||
/*REXX program compresses text using the LZW (Lempel─Ziv─Welch), and reconstitutes it.*/
|
||||
parse arg x /*get an optional argument from the CL.*/
|
||||
if x=='' then x= '"There is nothing permanent except change." ─── Heraclitus [540-475 BC]'
|
||||
say 'original text=' x
|
||||
cypher=LZWc(x) /*compress text using the LZW algorithm*/
|
||||
say; say 'reconstituted=' LZWd(cypher) /*display the original cypher text. */
|
||||
say; say ' LZW integers=' cypher /*also display the LZW integers used.*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
LZWc: procedure; parse arg y,,w $ @.; #=256 /*the LZW compress algorithm.*/
|
||||
do j=0 for #; _=d2c(j); @._=j; end /*j*/
|
||||
|
||||
do k=1 for length(y); _=w || substr(y,k,1)
|
||||
if @._=='' then do; $=$ @.w
|
||||
@._=#; #=#+1
|
||||
w=substr(y,k,1)
|
||||
end
|
||||
else w=_
|
||||
end /*k*/
|
||||
return strip($ @.w) /*remove any superfluous blanks*/
|
||||
/*────────────────────────────────────────────────────────────────────────────*/
|
||||
LZWd: procedure; parse arg w y,,@.; #=256 /*the LZW decompress algorithm.*/
|
||||
do j=0 for 256; @.j=d2c(j); end /*j*/
|
||||
$=@.w; w=$
|
||||
do k=1 for words(y); _=word(y,k)
|
||||
if @._\=='' | @.k==' ' then ?=@._
|
||||
else if _=# then ?=w || left(w,1)
|
||||
$=$ || ?
|
||||
@.#=w || left(?,1); #=#+1
|
||||
w=?
|
||||
end /*k*/
|
||||
return $
|
||||
do k=1 for length(y); _=w || substr(y, k, 1)
|
||||
if @._=='' then do; $=$ @.w; @._=#; #=#+1
|
||||
w=substr(y, k, 1)
|
||||
end
|
||||
else w=_
|
||||
end /*k*/
|
||||
return strip($ @.w) /*remove any superfluous blanks*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
LZWd: procedure; parse arg w y,,@.; #=256 /*the LZW decompress algorithm.*/
|
||||
do j=0 for #; @.j=d2c(j); end /*j*/
|
||||
$=@.w; w=$
|
||||
do k=1 for words(y); _=word(y, k)
|
||||
if @._\=='' | @.k==" " then ?=@._
|
||||
else if _=# then ?=w || left(w, 1)
|
||||
$=$ || ?
|
||||
@.#=w || left(?, 1); #=#+1
|
||||
w=?
|
||||
end /*k*/
|
||||
return $
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ $ include "seed7_05.s7i";
|
|||
|
||||
const func string: lzwCompress (in string: uncompressed) is func
|
||||
result
|
||||
var string: result is "";
|
||||
var string: compressed is "";
|
||||
local
|
||||
var char: ch is ' ';
|
||||
var hash [string] char: mydict is (hash [string] char).value;
|
||||
|
|
@ -17,19 +17,19 @@ const func string: lzwCompress (in string: uncompressed) is func
|
|||
if xstr in mydict then
|
||||
buffer &:= str(ch)
|
||||
else
|
||||
result &:= str(mydict[buffer]);
|
||||
compressed &:= str(mydict[buffer]);
|
||||
mydict @:= [xstr] chr(length(mydict));
|
||||
buffer := str(ch);
|
||||
end if;
|
||||
end for;
|
||||
if buffer <> "" then
|
||||
result &:= str(mydict[buffer]);
|
||||
compressed &:= str(mydict[buffer]);
|
||||
end if;
|
||||
end func;
|
||||
|
||||
const func string: lzwDecompress (in string: compressed) is func
|
||||
result
|
||||
var string: result is "";
|
||||
var string: uncompressed is "";
|
||||
local
|
||||
var char: ch is ' ';
|
||||
var hash [char] string: mydict is (hash [char] string).value;
|
||||
|
|
@ -43,10 +43,10 @@ const func string: lzwDecompress (in string: compressed) is func
|
|||
for ch range compressed do
|
||||
if buffer = "" then
|
||||
buffer := mydict[ch];
|
||||
result &:= buffer;
|
||||
uncompressed &:= buffer;
|
||||
elsif ch <= chr(255) then
|
||||
current := mydict[ch];
|
||||
result &:= current;
|
||||
uncompressed &:= current;
|
||||
chain := buffer & current;
|
||||
mydict @:= [chr(length(mydict))] chain;
|
||||
buffer := current;
|
||||
|
|
@ -56,7 +56,7 @@ const func string: lzwDecompress (in string: compressed) is func
|
|||
else
|
||||
chain := buffer & str(buffer[1]);
|
||||
end if;
|
||||
result &:= chain;
|
||||
uncompressed &:= chain;
|
||||
mydict @:= [chr(length(mydict))] buffer & str(chain[1]);
|
||||
buffer := chain;
|
||||
end if;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue