pub fn huffman_codes(text: &str) -> HashMap<char, String>Expand description
Huffman kodlari: har bir belgi uchun o’zgaruvchan uzunlikdagi ikkilik kod.
G’oya: tez-tez uchraydigan harfga qisqa kod, kam uchraydiganiga uzun kod beramiz. Ochko’z qadam: har safar eng kam uchraydigan ikkita tugunni birlashtiramiz.
"abracadabra": a=5, b=2, r=2, c=1, d=1
(11)
/ \
a(5) (6)
/ \
(2) (4)
/ \ / \
c(1) d(1) b(2) r(2)
a = 0, c = 100, d = 101, b = 110, r = 111Kodlar prefiksli (prefix-free): birortasi ikkinchisining boshi bo’lmaydi — shuning uchun ajratuvchi belgisiz ham bir ma’noda o’qiladi.
- Time: O(n + k log k), bu yerda k — turli belgilar soni.
- Natija: matn hajmi odatda 20–60% ga kamayadi (ZIP, JPEG, MP3 ichida ishlatiladi).
Bitta xil belgidan iborat matn uchun kod "0" bo’ladi.
§Misol
use rust_algorithms::greedy::huffman_codes;
let kodlar = huffman_codes("abracadabra");
assert_eq!(kodlar.len(), 5);
// eng ko'p uchraydigan 'a' eng qisqa kodni oladi
assert_eq!(kodlar[&'a'].len(), 1);
assert!(kodlar[&'c'].len() > kodlar[&'a'].len());
// prefiks-erkinlik: hech bir kod boshqasining boshi emas
let hammasi: Vec<&String> = kodlar.values().collect();
for a in &hammasi {
for b in &hammasi {
if a != b {
assert!(!b.starts_with(a.as_str()));
}
}
}