2015-06-15 22:36 GMT+02:00 Lumír Balhar <frenzy.madn...@gmail.com>: > Ahoj všem. > > Řeším s kamarádem jeden jeho projekt, jehož součástí je i Burrows-Wheelerova > transformace, která se používá před kompresí dat společně s Move to Front > transformací pro snížení entropie vstupních dat a tím zvýšení efektivity > kompresního algoritmu, kterému tyto dvě transformace předcházejí. > > Pochopení transformací není potřeba. U BWT se využívá tzv, buffer, který > obsahuje všechny možné rotace vstupních dat, takže například pro "ema má > maso" vypadá takto: > > 0 ema ma maso > 1 ma ma masoe > 2 a ma masoem > 3 ma masoema > 4 ma masoema > 5 a masoema m > 6 masoema ma > 7 masoema ma > 8 asoema ma m > 9 soema ma ma > 10 oema ma mas > > Pro malá data je to dobré, ale pro velká nelze mít celý buffer v paměti, > protože se pro každý vstupní znak navíc rozšíří o řádek i sloupec zároveň. > Napsal jsem tedy pro Buffer samostatnou třídu, kde pomocí __getitem__ > vygeneruji potřebný řádek posunem až ve chvíli, kdy je jeho obsah potřeba.
Ahoj, sort() používá jen operátor "<", takže stačí naimplementovat ten (i když s functools.total_ordering [0] není problém naimplementovat ty ostatní). Jen je potřeba mít objekt pro každý řádek. Když takový objekt obsahuje jen odkaz na původní řetězec, a číslo řádku, tak se ti snad všechny do paměti vejdou. Přikládám nástin toho, jak bych to řešil já (v py3). (Jestli se vyplatí při porovnávání generovat oba řádky a porovnat ty, nebo jako já porovnávat jednotlivé znaky v Pythonu, záleží na tom jak často ty řetězce mají dlouhé shodné prefixy.) [0] https://docs.python.org/3/library/functools.html#functools.total_ordering
class RotatedString: __slots__ = ['orig_string', 'n'] def __init__(self, orig_string, n): self.orig_string = orig_string self.n = n def __len__(self): return len(self.orig_string) def __str__(self): return self.orig_string[self.n:] + self.orig_string[:self.n] def __iter__(self): yield from self.orig_string[self.n:] yield from self.orig_string[:self.n] def __getitem__(self, i): return self.orig_string[(self.n + i) % len(self.orig_string)] def __lt__(self, other): if self.orig_string != other.orig_string: return self.orig_string < other.orig_string for c1, c2 in zip(self, other): if c1 != c2: return c1 < c2 base = 'ema má maso' for rs in sorted([RotatedString(base, i) for i, c in enumerate(base)]): print(rs)
_______________________________________________ Python mailing list python@py.cz http://www.py.cz/mailman/listinfo/python Visit: http://www.py.cz