Dekompresja RLE z pliku
Ostatnio zmodyfikowano 2016-11-01 16:59
Wojtek1243 Temat założony przez niniejszego użytkownika |
Dekompresja RLE z pliku » 2016-10-31 17:39:30 Witam. W jaki sposób z pliku pobrać dane do dekompresji np A10B2. Tak aby program wiedział, że ma powtórzyć litere A 10 razy, jeśli program pobiera tekst z pliku znak po znaku? Program najpierw pobierze 1 potem 0 i tu powstaje problem. Czy istnieje jakiś sposób aby pobrać liczbę w całości?
Próbowałem metodą if'ów na wyłapywanie cyfr i jeśli następny znak tez jest liczbą to mnoży te pierwszą razy 10 i dodaje te drugą pobraną, np 12 to 1*10+2 ale to sie nie sprawdza.
Pozdrawiam
|
|
michal11 |
» 2016-10-31 17:46:33 No to pokaż co masz, generalnie z tego co opisałeś to wystarczy traktować wczytywane znaki od litery do litery jako cyfrę. |
|
Wojtek1243 Temat założony przez niniejszego użytkownika |
» 2016-10-31 17:58:04 void compression_rle() { vector < char > data_vector; vector < char >::iterator it; file_to_vector_char( "to_compression_rle.a", data_vector ); cout << "Do kompresji" << endl << endl; print_vector( data_vector, it ); ofstream compressed_data_rle; compressed_data_rle.open( "compressed_rle.a", ios::trunc ); if( compressed_data_rle.is_open() ) { unsigned int nrepeats = 0; for( it = data_vector.begin() + 1; it != data_vector.end(); it++ ) { if( * it != *( it - 1 ) ) { if( nrepeats == 0 ) { compressed_data_rle << *( it - 1 ); } else { compressed_data_rle << nrepeats + 1; compressed_data_rle << *( it - 1 ); nrepeats = 0; } } else { nrepeats++; } } } else cout << "File doesn't exist" << endl; compressed_data_rle.close(); cout << "Po kompresji " << endl << endl; print_file( "compressed_rle.a" ); }
w ten sposób kompresuje. Pobieram z pliku znak po znaku do vectora char. i teraz przy dekompresji 'odwiedzam' kazdy element vectora i teraz pytanie jeśli mam do dekompresji np A12 to wyjdzie cos w stylu 'A', '1', '2' i nie mam pomysłu jak wyłuskać te liczbę 12 do zmiennej int żeby powtórzyć znak 'A' 12 razy |
|
j23 |
» 2016-10-31 18:32:31 Coś w ten deseń: auto i1 = data_vector.begin(); auto i2 = data_vector.end();
while( i1 != i2 ) { char ch = * i1++; int rep = 0; do { rep *= 10; rep += * i1++ - '0'; } while( i1 != i2 && isdigit( * i1 ) ); ... } |
|
Wojtek1243 Temat założony przez niniejszego użytkownika |
» 2016-10-31 19:24:48 Dzięki. Wypróbuje to co zaproponowałeś |
|
Wojtek1243 Temat założony przez niniejszego użytkownika |
» 2016-10-31 22:11:35 Ok napisałem. Mam jeszcze problem z wyliczaniem powtorzeń większych niz 99 przy dekompresji Używam kodu for( it = data_vector.begin(); it != data_vector.end(); it++ ) { if( isdigit( * it ) ) { if( !isdigit( *( it + 1 ) ) ) { ... } else { int next_digit = conv_char_to_int( *( it + 1 ) ); nrepeats =( nrepeats * 10 ) + next_digit; if( isdigit( *( it + 2 ) ) ) continue; to_repeat = *( it + 2 ); for( int i = 0; i < nrepeats - 1; i++ ) decompressed_data_rle << to_repeat; } } else { decompressed_data_rle << * it; } }
Chodzi o część kodu gdy następny znak jest tez liczba. Otóź mając liczbe powtorzen np 123 pobieranych z wektora jako '1', '2', '3' W załoźeniu program ma 1) najpierw pobrać aktualny znak (liczbe) 2) zorientowac sie ze nastepny znak to liczba pobrac ja do 'next_digit' 3) wyliczyc nrepeats mnożąc go razy 10 i dodajac nastepna liczbe 4) jesli jest wiecej liczb to wywolac continue przesuwajac iterator i wrocic do punktu 1) np chcac wyliczyc 123 wtedy: w pierwszej iteracji for 1*10+2 wyjdzie mu 12 potem contunue i druga iteracja 12*10+3 wyjdzie docelowe 123 co jest zle w kodzie i jak mógłbym to naprawić? Pozdrawiam |
|
j23 |
» 2016-11-01 10:13:03 A co, mój kod nie działa?
Oczywiście przy takim sposobie kodowania kompresja ciągów cyfr nie wchodzi w grę. |
|
Wojtek1243 Temat założony przez niniejszego użytkownika |
» 2016-11-01 16:59:28 Spróbuje to jakoś przez write zapisywać te dane jeśli chodzi o kompresje. |
|
« 1 » |