Jednoduchý algoritmus: ukladá (počet, znak).
def rle_encode(data: str) -> str:
if not data:
return ""
result = []
count = 1
for i in range(1, len(data)):
if data[i] == data[i - 1]:
count += 1
else:
result.append(f"{count}{data[i-1]}")
count = 1
result.append(f"{count}{data[-1]}")
return "".join(result)
def rle_decode(data: str) -> str:
result = ""
count = ""
for char in data:
if char.isdigit():
count += char
else:
result += char * int(count)
count = ""
return result
text = "WWWWWWWWWWWWBWWWWWWWWWWWWBBBWWWWWWWWWWWWWWWWWWWWWWBWWWWWWWWWWWWWW"
encoded = rle_encode(text)
decoded = rle_decode(encoded)
print(encoded) # 12W1B12W3B24W1B14W
print(decoded == text) # True
Používa posunutie (offset), dĺžku, ďalší znak.
def lz77_encode(data: str, window_size=20):
i = 0
output = []
while i < len(data):
match_length = 0
match_distance = 0
start = max(0, i - window_size)
for j in range(start, i):
length = 0
while (i + length < len(data) and
data[j + length] == data[i + length]):
length += 1
if j + length >= i:
break
if length > match_length:
match_length = length
match_distance = i - j
next_char = data[i + match_length] if i + match_length < len(data) else ''
output.append((match_distance, match_length, next_char))
i += match_length + 1
return output
def lz77_decode(encoded):
result = ""
for distance, length, char in encoded:
if distance == 0:
result += char
else:
start = len(result) - distance
for i in range(length):
result += result[start + i]
result += char
return result
text = "ABABABA"
encoded = lz77_encode(text)
decoded = lz77_decode(encoded)
print(encoded)
print(decoded)
Používa slovník: (index, znak).
def lz78_encode(data: str):
dictionary = {}
result = []
buffer = ""
index = 1
for char in data:
if buffer + char in dictionary:
buffer += char
else:
result.append((dictionary.get(buffer, 0), char))
dictionary[buffer + char] = index
index += 1
buffer = ""
if buffer:
result.append((dictionary[buffer], ""))
return result
def lz78_decode(encoded):
dictionary = {0: ""}
result = ""
index = 1
for idx, char in encoded:
entry = dictionary[idx] + char
result += entry
dictionary[index] = entry
index += 1
return result
text = "ABAABABAABAB"
encoded = lz78_encode(text)
decoded = lz78_decode(encoded)
print(encoded)
print(decoded)
Používa sa v GIF, PDF, ZIP.
def lzw_encode(data: str):
dictionary = {chr(i): i for i in range(256)}
current = ""
result = []
code = 256
for char in data:
combined = current + char
if combined in dictionary:
current = combined
else:
result.append(dictionary[current])
dictionary[combined] = code
code += 1
current = char
if current:
result.append(dictionary[current])
return result
def lzw_decode(data):
dictionary = {i: chr(i) for i in range(256)}
result = ""
prev = chr(data[0])
result += prev
code = 256
for curr_code in data[1:]:
if curr_code in dictionary:
entry = dictionary[curr_code]
elif curr_code == code:
entry = prev + prev[0]
else:
raise ValueError("Invalid LZW code")
result += entry
dictionary[code] = prev + entry[0]
code += 1
prev = entry
return result
# RLE → jednoduché opakovania (ASCII art)
# LZ77 → sliding window (gzip základ)
# LZ78 → slovník
# LZW → optimalizovaná verzia (GIF, PDF)