Deivid Temat założony przez niniejszego użytkownika |
[Rozdział 28] Czy da się to napisać prościej? » 2015-11-14 23:38:40 Witajcie, właśnie rozwiązałem zadanie domowe. Mam kilka pytań: 1. Czy o takie rozwiązanie chodziło? (patrz kod programu) 2. Czy może nie trzeba było sprawdzać pozycji frazy tylko wpisać na sztywno obliczając ją sobie (niby byłoby łatwiej) 3. Dlaczego coś takiego działa: do { sTekst.erase( znalezione_spacje_x2, dlugosc_spacji_x2 ); znalezione_spacje_x2 = sTekst.find( spacja_x2 ); } while( znalezione_spacje_x2 != string::npos );
zgodnie z rozdziałem 27 brakuje tutaj: do { sTekst.erase( znalezione_spacje_x2, dlugosc_spacji_x2 ); znalezione_spacje_x2 = sTekst.find( spacja_x2, znalezione_spacje_x2 + spacja_x2.size() ); } while( znalezione_spacje_x2 != string::npos );
Ktoś pomoże zrozumieć? Edit. // Na chłopski rozum pojmuję to tak. Że w tym programie po prostu nie muszę korzystać z dodatków funkcji .find, przydają się one tylko gdy muszę te dane wypisać na ekran, a gdy potrzebuję je wewnątrz programu to .find zadziała w zwykłej pętli. Kod programu:
#include <iostream> #include <string> using namespace std;
std::string konwertuj( std::string & sTekst ) { std::string sWynik; string spacja_x2 = " "; size_t dlugosc_spacji_x2 = spacja_x2.size(); size_t znalezione_spacje_x2 = sTekst.find( spacja_x2 ); do { sTekst.erase( znalezione_spacje_x2, dlugosc_spacji_x2 ); znalezione_spacje_x2 = sTekst.find( spacja_x2 ); } while( znalezione_spacje_x2 != string::npos ); string znak_nierownosci_b = "<b>"; string znak_kwadratu_b = "[b]"; size_t dlugosc_znaku_nierownosci_b = znak_nierownosci_b.size(); size_t znalezione_znaki_nierownosci_b = sTekst.find( znak_nierownosci_b ); do { sTekst.erase( znalezione_znaki_nierownosci_b, dlugosc_znaku_nierownosci_b ); sTekst.insert( znalezione_znaki_nierownosci_b, znak_kwadratu_b ); znalezione_znaki_nierownosci_b = sTekst.find( znak_nierownosci_b ); } while( znalezione_znaki_nierownosci_b != string::npos ); string znak_nierownosci2_b = "</b>"; string znak_kwadratu2_b = "[/b]"; size_t dlugosc_znaku_nierownosci2_b = znak_nierownosci2_b.size(); size_t znalezione_znaki_nierownosci2_b = sTekst.find( znak_nierownosci2_b ); do { sTekst.erase( znalezione_znaki_nierownosci2_b, dlugosc_znaku_nierownosci2_b ); sTekst.insert( znalezione_znaki_nierownosci2_b, znak_kwadratu2_b ); znalezione_znaki_nierownosci2_b = sTekst.find( znak_nierownosci2_b ); } while( znalezione_znaki_nierownosci2_b != string::npos ); sWynik = sTekst; return sWynik; } int main() { std::string tekst = "<b>to jest </b> testowy napis <b>:)"; std::cout << konwertuj( tekst ) << std::endl; return 0; }
|
|
pekfos |
» 2015-11-15 00:03:40 Czy o takie rozwiązanie chodziło? |
Jeśli działa dla dowolnego tekstu, to tak. Dlaczego coś takiego działa:
do { sTekst.erase( znalezione_spacje_x2, dlugosc_spacji_x2 ); znalezione_spacje_x2 = sTekst.find( spacja_x2 ); } while( znalezione_spacje_x2 != string::npos );
zgodnie z rozdziałem 27 brakuje tutaj:
do { sTekst.erase( znalezione_spacje_x2, dlugosc_spacji_x2 ); znalezione_spacje_x2 = sTekst.find( spacja_x2, znalezione_spacje_x2 + spacja_x2.size() ); } while( znalezione_spacje_x2 != string::npos );
|
W rozdziale 27 w tej pętli nie było usuwania. Jak chcesz znaleźć wszystkie wystąpienia danej frazy, zaczynasz następne wyszukiwanie od końca poprzedniej znalezionej frazy, by nie znajdywać jej na nowo w nieskończoność. Tu fraza jest usuwana, więc nie znajdziesz tego samego wystąpienia 2 razy. |
|
Deivid Temat założony przez niniejszego użytkownika |
» 2015-11-15 00:07:50 Tak, działa. Jednak kiedyś w rozdziale losowania bez powtórzeń źle zrozumiałem polecenie i wykonałem złe losowanie (do dziś pamiętam mój błąd, tak więc wolę się upewnić i tutaj). Chce się uczyć poprawnie pisać kod, dlatego też pytam czy da się to napisać prościej / mniejszą ilością kodu. Co do tego mojego drugiego pytania dlaczego to działa, mniej więcej rozumiem. Ale jeszcze nie do końca, heh. Jeśli patrzę na rozdziały przy pisaniu programu to jakoś ogarnę, może jeśli kiedyś znajdę pracę w tej branży to wyćwiczę pracę z tekstem :) Edit. Chociaż jak przeczytałem kilka razy Twoją wypowiedź zaczyna mi się robić coraz jaśniej w tej pustej głowie o co chodzi. Dzięki :) czasami się przydaje, jednak ten przypadek nie zostanie omówiony ponieważ praktycznego zastosowania w swoich programach nie znajdziesz z wiedzą, którą posiadasz na chwilę obecną. Przejdźmy teraz do przykładu: |
- Niestety autor kursu nie przewidział, że jednak dokładne wyjaśnienie się przyda, bo przy następnej lekcji już się wykorzystało tą wiedzę. |
|
j23 |
» 2015-11-15 10:15:18 A propos szukania spacji: znalezione_spacje_x2 = sTekst.find( spacja_x2 ); |
tak zrób, będzie bardziej optymalnie: znalezione_spacje_x2 = sTekst.find( spacja_x2, znalezione_spacje_x2 ); Nie będziesz przeszukiwał tekstu od początku, tylko od miejsca znalezienia spacji. Tu wersja najoptymalniejsza: auto i1 = sTekst.begin(); auto i2 = i1; auto i3 = sTekst.end();
while( i1 != i3 ) { * i2 = * i1++; if( * i2 == ' ' ) while( i1 != i3 && * i1 == ' ' ) ++i1; ++i2; }
sTekst.erase( i2, i1 ); Tylko jedno erase z końca sTekst (co nie jest bez znaczenia) dla wszystkich spacji. |
|
Deivid Temat założony przez niniejszego użytkownika |
» 2015-11-15 20:01:48 Dzięki za kolejną wskazówkę jak prawidłowo wykorzystać funkcję .find(). Jednak następnego fragmentu Twojego postu nie rozumiem, nie przerobiłem jeszcze wskaźników, gdy już się ich nauczę z pewnością wrócę tutaj aby przeanalizować Twój kod. |
|
« 1 » |