ByteRun jest również algorytmem kompresującym strumienia informacji. Tu również kompresujemy powtarzające się symbole w ciągu jednak z pewnymi usprawnieniami. Podczas kodowania łańcucha wejściowego mogą zdarzyć się nam dwie sytuacje:
- symbole następujące po sobie różnią się od siebie (przykładowo
1 2 3 4 5
), - symbole następujące po sobie są identyczne (przykładowo
1 1 1 1 1
)
Sam kodogram w obu przypadkach wygląda podobnie. Na początku występuje liczba \(n\) a za nią następuje zakodowana informacja. Jeżeli \(n\in<0,127>\) to mamy do czynienia z pierwszym przypadkiem to po niej następuje \(n+1\) znaków przepisanych bez zmiany. Jeżeli zaś \(n\in<-127,-1>\) to mamy do czynienia z drugim przypadkiem i po liczbie \(n\) wystąpi tylko jeden znak, który po odkodowaniu powinien wystąpić \(-n+1\) razy. Na podstawie wzorów można łatwo wywnioskować, że maksymalna długość jednej paczki informacji, jaką możemy spakować, nie będzie większa niż ~\(128\) znaków.
Przykład:
Wiadomość: [5,5,5,1,2,3,4,4,1,2,3,4]
Kodogram: [-2,5,2,1,2,3,-1,4,3,1,2,3,4]
Uprzedzając pytania: tak w nie sprzyjających okolicznościach tu też zakodowana wiadomość może mieć mniej bajtów przed kompresją niż po niej. Wiec też można złożyć ten najbardziej niekorzystny buffor:
*2) np.zeros(np.prod(data.shape)
Warto napisać sobie dwie funkcje pomocnicze do przeszukiwania zbioru przy użyciu zwykłego fora
z break
(nie np.where
), które znacząco ułatwią prace nad implementacją tego algorytmu:
- Pierwsza: znajdowanie jak długo elementy się powtarzają,
- druga: znajdowanie jak długo elementy są różne, czy tak długo aż nie znajdzie się para elementów identycznych jeden za drugim (czyli
x[i]==x[i+1]
).
Podczas kompresji zaczynamy od sprawdzenia, czy bieżący element jest identyczny z następnym — wtedy wykorzystujemy funkcję pierwszą, a jeżeli nie to uruchamiamy funkcję drugą. Potem sprawdzamy, czy licznik jest większy niż 128 i jeżeli tak to zapisujemy fragmenty. Do tego można wykorzystać pętlę while
:
while licznik >128:
#zapis
-=128
licznik #zapis
Sam #zapis
będzie się różnił w zależności, czy znaki się powtarzają lub różnią. Trzeba to zastąpić odpowiednim kodem na bazie informacji z początku tej części instrukcji.