Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Rozdział 28 - usuwanie spacji

Ostatnio zmodyfikowano 2017-08-29 19:49
Autor Wiadomość
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

C/C++
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, ' ' ); // kompilator wskazuje, że w tym miejscu jest coś nie tak jednak dokładnie sprawdziłem składnie metody find i wszystko sie zgadza (first,last,value)
        szukane2 = sTekst.find( i + 1, i + 2, ' ' );
       
        if( szukane1 != string::npos && szukane2 != string::npos )
             sWynik.erase( i, 1 );
       
    }
   
    return sWynik;
}
P-164366
maly7
» 2017-08-29 18:20:57
Z dokumentacji C++:
C/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ąć:
C/C++
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;
}
P-164367
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

C/C++
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;
}
P-164369
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:
C/C++
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 )
P-164370
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ść.
P-164371
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...
P-164372
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.
P-164373
« 1 »
  Strona 1 z 1