Метод Шеннона-Фано
В цьому методі для кожного символа формується бітовий код, довжина якого залежить від частоти появи символа. Чим менша частота, тим довший код. Визначення частоти (ймовірності) символа буває статичне (на основі таблиці даних) або динамічне (коли відомості про ймовірність появи символів визначаються на основі обробки потоку даних).
Кодування здійснюється таким чином (рис. 1):
Всі символи записуються в таблицю по зменшенню їх частоти. Потім вони поділяються на дві групи так, щоб суми частот для отриманих груп були максимально близькі. Для першої групи перший біт коду встановлюється рівним 1, а для другої – 0. Потім групи знову поділяємо на дві і визначаємо наступні розряди коду. Процес продовжується поки в групі не залишиться тільки один символ.
Номер Символ Частота Код
1 a 10 11
2 b 8 10
-----------------------------‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑‑----------------------------
3 c 6 011
4 d 5 010
5 e 4 001
6 f 3 000
Рис. 1.
Можливий варіант програмної реалізації методу базується на формуванні і обробці такої таблиці
Nгр | Np | Nk | S | Код |
Ця таблиця забезпечує зручний запис алгоритму поділу на підгрупи і формування кодів. Перша група (Nгр=1) складається з двох підгруп: перша - починається з першого символа (Np=1) і закінчується другим (Nк=2), друга – починається з третього символа (Nр=3) і закінчується шостим (Nк=6). Сума частот першої підгрупи S=18, другої S=18. Друга група (Nгр=2) формується в результаті поділу першої підгрупи з першої групи і складається теж з двох підгруп: перша – починається з першого символа (Nр=1) і ним закінчується (Nк=1), друга – починається другим символом (Nр=2) і ним закінчується (Nк=2). Третя група описує процес поділу другої підгрупи з першої групи. Процуес продовжується до тих пір поки кожна підгрупа не буде складатися тільки з одного символа (Nр=Nк). Відповідний новий біт коду кожної групи визначається таким чином: для першої підгрупи він встановлюється рівним одиниці, а для другої підгрупи – нулю.
Нижче приведений можливий варіант демонстраційної програми і результати її роботи
implicit integer*2(j),character*1(z)
dimension jmp(12),jmk(12),jms(12),jml(12),zmk(12,5),zm(6),jmc(6)
data zm/'a','b','c','d','e','f'/,jmc/10,8,6,5,4,3/
js=0
do 100 j=1,12
100 jml(j)=0
do 1 j=1,6
1 js=js+jmc(j)
jp=1
jk=6
ju=0
jz=1
12 jdr=32000
jmp(jz)=jp
jmk(jz+1)=jk
js1=0
jv=jp
jvr=jv
9 js1=js1+jmc(jv)
js2=js-js1
jd=js2-js1
if(abs(jd).ge.jdr) go to 11
jdr=jd
jms(jz)=js1
jms(jz+1)=js2
jvr=jv
if(jd.le.0) go to 11
jv=jv+1
go to 9
11 jmk(jz)=jvr
jmp(jz+1)=jvr+1
if(ju.eq.0) go to 50
jml(jz)=jml(ju)
jml(jz+1)=jml(ju)
do 20 j=1,jml(ju)
zmk(jz,j)=zmk(ju,j)
20 zmk(jz+1,j)=zmk(ju,j)
50 jml(jz)=jml(jz)+1
zmk(jz,jml(jz))='1'
jml(jz+1)=jml(jz+1)+1
zmk(jz+1,jml(jz+1))='0'
jz=jz+2
15 ju=ju+1
if(ju.ge.jz) go to 17
jp=jmp(ju)
jk=jmk(ju)
js=jms(ju)
if(jp.eq.jk) go to 15
if(jp+1.lt.jk) go to 12
jmp(jz)=jp
jms(jz)=jmc(jp)
jmk(jz+1)=jk
jms(jz+1)=jmc(jk)
jvr=jp
go to 11
17 do 30 j=1,10
30 write(6,31) jmp(j),jmk(j),jms(j),jml(j),(zmk(j,jj),jj=1,5)
31 format(' ',4i4,1x,5a1)
stop
end
1 2 18 1 1
3 6 18 1 0
1 1 10 2 11
2 2 8 2 10
3 4 11 2 01
5 6 7 2 00
3 3 6 3 011
4 4 5 3 010
5 5 4 3 001
6 6 3 3 000
Кодування Шеннона-Фано неоднозначне. В залежності від варіанту поділу на групи (при однаковій різниці частот між ними) можуть бути отримані різні коди для символів (рис. 2).
Символ Частота Код Символ Частота Код
с 22 11 с 22 11
e 20 101 e 20 10
h 16 100 --------------------------------------------
----------------------------------------------- h 16 011
i 16 011 і 16 010
a 10 010 a 10 001
k 10 001 k 10 0001
m 4 0001 m 4 00001
b 2 0000 b 2 00000
Рис. 2.