W przeciwnym razie będzie sapał i dmuchał i wysadził dom w powietrze!
To było zupełnie nieistotne. To wyzwanie dotyczy kodowania Huffmana . Jego istotą jest częstotliwość znaków w danym tekście wykorzystywana do skrócenia jego reprezentacji. Innymi słowy, powiedzmy, że nasz alfabet ma a
szerokość z
i przestrzeń. To 27 znaków. Każdy z nich może być jednoznacznie zakodowany w zaledwie 5 bitach, ponieważ 5 bitów ma wystarczająco dużo miejsca na 32 znaki. Jednak w wielu sytuacjach (takich jak angielski lub ogólnie języki) niektóre znaki występują częściej niż inne. Możemy użyć mniej bitów dla częstszych znaków i (być może) więcej bitów dla rzadszych znaków. Zrobione dobrze, istnieje ogólna oszczędność liczby bitów, a oryginalny tekst można nadal wyjątkowo odtworzyć.
Weźmy jako przykład „to pytanie dotyczy kodowania huffmana”. Ten tekst ma 37 znaków, czyli 37 * 8 = 296 bitów normalnie, choć tylko 37 * 5 = 185 bitów, jeśli użyjemy tylko 5 bitów na każdy znak. Miej to w pamięci.
Oto (sorta) tabela każdego znaku i ich częstotliwości w tekście, posortowana od najbardziej do najmniejszej (gdzie _ oznacza spację):
_ 5
i 4
n 3
o 3
s 3
t 3
u 3
a 2
f 2
h 2
b 1
c 1
d 1
e 1
g 1
m 1
q 1
Powiązane optymalne kodowanie może być:
_ 101
i 011
n 1100
o 1101
s 1110
t 1111
u 001
a 10011
f 0001
h 0101
b 00000
c 00001
d 01000
e 01001
g 10000
m 10001
q 10010
Od razu powinno być jasne, że będzie to lepsze kodowanie niż tylko użycie 5 bitów na każdy znak. Sprawdźmy jednak, o ile lepiej!
145 bitów , w porównaniu do 185! To oszczędność 40 bitów, czyli nieco ponad 20%! (To oczywiście zakłada, że informacje o strukturze są dostępne do dekodowania.) To kodowanie jest optymalne, ponieważ nie można usunąć więcej bitów przez zmianę reprezentacji dowolnego znaku.
Zadanie
- Napisz program lub funkcję z jednym parametrem, który ...
- Pobiera dane wejściowe ze STDIN (lub odpowiednika) lub jako pojedynczy argument.
- Wypisuje optymalne kodowanie Huffmana, jak wyżej, przy użyciu znaków posortowanych według częstotliwości (kolejność w klasie częstotliwości nie ma znaczenia).
- Możesz założyć, że znaki na wejściu są ograniczone do zakresu ASCII
32..126
plus nowego wiersza. - Możesz założyć, że dane wejściowe nie mają więcej niż 10 000 znaków (najlepiej teoretycznie dane wejściowe powinny być nieograniczone).
- Twój kod powinien zakończyć się dość szybko. Powyższy przykład w najgorszym przypadku nie powinien zająć więcej niż minutę. (Ma to na celu wykluczenie brutalnej siły.)
- Punktacja jest w bajtach.
Przykłady
x
---
x 0
xxxxxxxxx
---
x 0
xxxxxxxxy
---
x 0
y 1 (these may be swapped)
xxxxxyyyz
---
x 0
y 10
z 11
uuvvwwxxyyzz
--- (or)
u 000 000
v 001 001
w 100 010
x 101 011
y 01 10
z 11 11
this question is about huffman coding
---
101
i 011
n 1100
o 1101
s 1110
t 1111
u 001
a 10011
f 0001
h 0101
b 00000
c 00001
d 01000
e 01001
g 10000
m 10001
q 10010
Miłego kodowania!
Zauważ, że to podobne pytanie jest ściśle powiązane, nawet do tego stopnia, że jest to duplikat. Jednak dotychczasowy konsensus w sprawie Meta jest taki, że starszy należy uważać za duplikat tego.
this question is about huffman coding
policzyłem liczbę bitów jako 145 , a nie 136.