thomson92 Temat założony przez niniejszego użytkownika |
Rozdział 28 - usuwanie spacji » 2017-08-29 18:00:29 Próbowałem na wiele sposobów rozwiązać te zadanie i obecnie mam wrażenie, że jestem na dobrej drodze. Niestety kod się nie kompiluje i za cholere nie wiem dlaczego. Do funkcji "konwertuj" dodałem 2 zmienne za pomocą, których sprawdzam czy dwa pola obok siebie nie zawierają spacji, jeżeli tak to usuwam pole z lewej strony i pętla leci dalej. Byłym bardzo wdzięczny za jakiekolwiek wskazówki. Pozdrawiam string konwertuj( string & sTekst ) { string sWynik; size_t szukane1; size_t szukane2; for( int i = 0; i < sTekst.size() - 1; i++ ) { szukane1 = sTekst.find( i, i + 1, ' ' ); szukane2 = sTekst.find( i + 1, i + 2, ' ' ); if( szukane1 != string::npos && szukane2 != string::npos ) sWynik.erase( i, 1 ); } return sWynik; }
|
|
maly7 |
» 2017-08-29 18:20:57 Z dokumentacji C++: size_t find( const string & str, size_t pos = 0 ) const; size_t find( const char * s, size_t pos = 0 ) const; size_t find( const char * s, size_t pos, size_t n ) const; size_t find( char c, size_t pos = 0 ) const;
Dodatkowo nie przypisujesz żadnej wartości zmiennej sWynik więc nie możesz z niej nic usuwać. W ogóle nie musisz używać metody find, wystarczy porównać poszczególny znak i jeśli jest to spacja to go usunąć: string konwertuj( const string & sTekst ) { string sWynik = sTekst; for( size_t i = 0; i < sWynik.size() - 1; ++i ) { if( sWynik[ i ] == ' ' && sWynik[ i + 1 ] == ' ' ) { sWynik.erase( i--, 1 ); } } return sWynik; } |
|
thomson92 Temat założony przez niniejszego użytkownika |
» 2017-08-29 18:42:13 Faktycznie... sprawdziłem funkcje find nie metode :( Tak jak się spodziewałem, istnieje dużo łatwiejszy sposób na zrobinie tego zadania a ja jak zwykle robię sobie pod górkę :D zazwyczaj unikam patrzenia na przykłady innych osób żeby sobie nie sugerować sposobu działania stąd taki dziwaczny kod. Dzięki za pomoc. Edit. Teraz kod wydaje się być ok jednak wciąż mam błąd przy kompilacji. http://i.imgur.com/2Oswjzl.png string konwertuj( string & sTekst ) { string sWynik = sTekst; for( int i = 0; i <= sTekst.size() - 1; i++ ) { if( sWynik[ i ] == ' ' && sWynik[ i + 1 ] == ' ' ) sWynik.erase( i--, 1 ); } for( int i = 0; i <= sTekst.size() - 1; i++ ) { if( sWynik[ i ] == '<' ) sWynik[ i ] = '['; if( sWynik[ i ] == '>' ) sWynik[ i ] = ']'; } return sWynik; }
|
|
maly7 |
» 2017-08-29 19:26:00 Out of range czyli wykraczasz poza zakres stringa. Musisz dać < a nie <=. Powinno być tak: for( int i = 0; i < sTekst.size() - 1; i++ ) <= sTekst.size() - 1 == < sTekst.size() W pętli używasz i + 1 więc musisz sprawdzać elementy bez ostatniego. Oraz dodatkowo polecam uzyć tylko jednej pętli for. Zmniejszy to czas wykonywania funkcji: string konwertuj( const string & sTekst ) { string sWynik = sTekst; for( size_t i = 0; i < sWynik.size(); ++i ) { if( sWynik[ i ] == '<' ) sWynik[ i ] = '['; else if( sWynik[ i ] == '>' ) sWynik[ i ] = ']'; else if( i < sWynik.size() - 1 && sWynik[ i ] == ' ' && sWynik[ i + 1 ] == ' ' ) sWynik.erase( i--, 1 ); } return sWynik; } Zauważyłem błąd w moim poprzednim kodzie (w poprzednik poscie), zamiast: for( size_t i = 0; i < sTekst.size() - 1; ++i ) powinno być for( size_t i = 0; i < sWynik.size() - 1; ++i ) |
|
garlonicon |
» 2017-08-29 19:36:48 Może lepiej zamiast kopiować na początku całość, to podczas przechodzenia przez cały tekst wstawiać właściwe znaki w pętli przez push_back() ? Wtedy nie trzeba niczego usuwać - od razu powstaje właściwa treść. |
|
thomson92 Temat założony przez niniejszego użytkownika |
» 2017-08-29 19:40:06 Ta wersja z tego co widze chyba była ok i <= sWynik.size() - 1; Ponieważ na koniec odejmuje 1 więc wszystko sie zgadza. Zaczeło działać jak zmieniłem. sTekst.size() na sWynik.size() Nie mam pojęcia dlaczego. Myślałem, że mogę tutaj sprawdzić długość ciągu sTekst... |
|
maly7 |
» 2017-08-29 19:49:03 Ale zauważ, że w trakcie usuwasz znaki ze stringa sWynik więc rozmiar się zmniejsza, a rozmiar sTekst ciągle pozostaje taki sam i może być większy niż rozmiar sWynik (wtedy wyjdziesz poza zakres sWynik). Co do i <= sWynik.size() - 1; to odejmujesz 1 ale masz <= więc również wykona się pętla dla elementu ostatniego, więc wtedy nie ma elementu i+1 (ostatni + 1).
Faktycznie może lepiej kopiować do stringa wynikowego pojedyncze znaki, jak to napisał garlonicon. |
|
« 1 » |