Ciąg można utworzyć na dwa główne sposoby w C++. Ciąg można utworzyć jako stały wskaźnik do sekwencji znaków. String można również utworzyć, tworząc instancję obiektu ciągów z klasy ciągów. Ten artykuł dotyczy obiektów stringowych utworzonych z klasy ciągów. Oznacza to, że biblioteka ciągów musi zostać uwzględniona w celu wykonania próbek kodu w tym artykule.
Obiekt ciągów to struktura danych, w której literał String jest listą. Każda postać ma jeden element na liście. I tak dosłownie można obsługiwać jak szereg elementów.
W tym artykule wyjaśniono klasyczne obejście odwrócenia ciągu w C++. To zasadniczo itera to dosłowne, zacofane. Posiadanie podsumowującej wiedzy na temat iteracji do przodu umożliwia czytelnikowi lepsze zrozumienie odwrotnej iteracji. Ten artykuł dotyczy obiektów stringowych utworzonych z klasy ciągów.
Cały kod ciągu tego samouczka jest zapisywany w funkcji C ++ main (), chyba że wskazano inaczej.
Treść artykułu
Iteracja do przodu
Iterator jest klasą wskaźnika, z której można utworzyć obiekty iteratora. Obiekt iteratora można użyć do skanowania elementów ciągów od początku listy ciągów do końca listy ciągów. Funkcja elementu ciągów, początek (), zwraca iterator, który wskazuje na pierwszy element literału struny. Można go zwiększyć, dopóki nie osiągnie, tuż po ostatnim elemencie ciągów. Funkcja elementu ciągów, end (), zwraca iterator, który wskazuje tuż po ostatnim elemencie literału łańcucha. Można go zmniejszyć, dopóki nie dotrze, ostatni element ciągu. Te dwa iteratory są uważane za iteratory do przodu, chociaż drugi itera.
W przypadku obiektu ciągów o nazwie zmiennej, STR, następujące instrukcje zwróci początkowe iterator:
String :: iterator p = str.zaczynać();
Tutaj P jest początkowym iteratorem. Iterator końcowy może zostać zwrócony przez następujące oświadczenie:
String :: iterator q = str.koniec();
Tutaj Q jest końcowym iteratorem. P i Q powyżej są tego samego typu, a nawet można je zamienić.
Poniższy kod drukuje wszystkie znaki ciągu, od początku do końca:
String str = „v”, „w”, 'x', 'y', 'z', '\ 0';
for (String :: iterator p = str.zaczynać(); P != str.koniec(); P ++)
Cout << *p << ";
Cout << endl;
Wyjście to:
V W x y z
„\ 0” nie należy drukować. Powinien być tam, aby zaznaczyć koniec literatu smyczkowego. Zwróć uwagę, jak uzyskano iterator początkowy. Iteracja skanuje listę żądła od początku do końca, porównując iterator każdego elementu z zwróconym przez Str.zaczynać(); Po przyrostu. Kiedy zwrócony iterator jest tym tuż po ostatnim elemencie, iteracja się zatrzymuje. Iterator jest zwiększany lub zmniejszany w taki sam sposób, jak indeks. Wyrażenie *p zwraca wartość wskazaną przez iterator, p.
Poniższy kod drukuje wartości w ciągu, od ostatniego znaku do pierwszego znaku, za pomocą końcowego iteratora:
string str = "vwxyz";
String :: iterator q = str.koniec();
dla (q = --q; q> = str.zaczynać(); Q--)
Cout << *q << ";
Cout << endl;
Wyjście to:
Z y x w v
To jest pośrednie odwrócenie łańcucha. Końcowy iterator wskazuje tuż po zakończeniu literatu sznurka, a taki punkt nie jest elementem. Aby wskazał ostatni element, należy go zmniejszyć. Stamtąd iteracja może cofnąć się.
Z tego powodu końcowy iterator został ogłoszony poza pętlą. Początkowa wartość iteratora w pętli jest pojedynczym spadkiem. Iterator jest zmniejszany krokami, aż osiągnie pierwszy element, jak wskazuje „Str.zaczynać()". To nieformalny sposób na iterację zacofania. Oznacza to, że jest to nieformalny sposób odwrócenia wektora (pośrednio).
Zmiana charakteru elementu
Obiekt ciągów jest strukturą danych, w której literał łańcuchowy jest z listy. Lista składa się z elementów. Każdy element ma charakter, a ten znak jest wartością elementu. Znaki są również wartościami ciągu. Pełny literał ciągów to wartość obiektu ciągów.
Gdy deklaracja obiektu ciągów nie jest poprzedzona przez Const (dla stałej), wartość dowolnego elementu w ciągu można zmienić. Ilustracja:
string str = "vwxyz";
String :: iterator q = str.koniec();
Q--; Q--; Q--;
*q = „a”;
String :: Iterator B = Str.koniec();
dla (b = - -b; b> = str.zaczynać(); B--)
Cout << *B << ";
Cout << endl;
Wyjście to:
z y a w v
"Q-; Q-; Q-;„Zmniejszyłem końcowy iterator 3 razy, aby wskazać„ c ”.
Gdy deklaracja obiektu String jest poprzedzona Const, znaki są tylko do odczytu. W przypadku takiego kodu zwrócone iterator musi być Const_iterator. W takim przypadku kod się nie kompiluje. Poniższy kod wyda komunikat o błędzie:
const string str = "vwxyz";
String :: const_iterator q = str.koniec();
Q--; Q--; Q--;
*q = „a”;
Odwrotna iteracja
Iterator używany z odwrotną iteracją jest odwrotna_. Kolejną funkcją członka klasy ciągów jest, Rend (), który zwraca iterator, który wskazuje tuż przed pierwszym elementem obiektu String. Mimo to kolejną funkcją członkowską klasy ciągów jest rbegin (), która zwraca iterator, który wskazuje ostatni element obiektu string. Poniższy kod ilustruje użycie zwróconego rewersa_iteratora, odczytu w kierunku do przodu, od pierwszego elementu do ostatniego elementu:
string str = "vwxyz";
String :: reverse_iterator p = str.rozdzierać();
dla (p = -p; p> = str.rbegin (); P--)
Cout << *p << ";
Cout << endl;
Wyjście to:
V W x y z
Zauważ, że z odwrotnym_teratorem ++ jest - i =, w stanie while.
Poniższy kod iteruje wstecz, używając iteratora rbegin ():
string str = "vwxyz";
for (String :: reverse_iterator q = str.rbegin (); Q <= str.rend(); q++)
Cout << *q << ";
Cout << endl;
Wyjście to:
Z y x w v
Znowu ++ jest używany zamiast - i = .
Zmiana charakteru elementu
Gdy deklaracja obiektu ciągów nie jest poprzedzona przez Const (dla stałej), wartość dowolnego elementu w ciągu można zmienić. Ilustracja:
string str = "vwxyz";
String :: reverse_iterator q = str.rbegin ();
Q ++; Q ++;
*q = „a”;
for (String :: reverse_iterator b = str.rbegin (); B <= str.rend(); B++)
Cout << *B << ";
Cout << endl;
Wyjście to:
z y a w v
Iterator rbegin (), Q, jest dwa razy zmniejszany „Q ++; Q ++; ” wskazywać na „c”, ponieważ początkowo wskazuje na ostatni element.
Jeśli obiekt ciągów jest poprzedzony Const, nie można zmienić żadnych znaków za pomocą dowolnego rodzaju iteratora. Kompilator wyda komunikat o błędzie dla następującego kodu, ponieważ kod próbuje zmodyfikować wartość „C”:
const string str = "vwxyz";
String :: const_reverse_iterator q = str.rbegin ();
Q ++; Q ++;
*q = „a”;
Ciąg stała iteracja odwrotna
Const_reverse_iterator jest zwracany przez funkcję członka, crbegin (). crbegin () jest jak rbegin (), ale wartość wskazana przez jego iteratora nie można zmienić. Const_reverse_iterator jest również zwracany przez inną funkcję członka, Crend (). Crend () jest jak Rend (), ale wartość wskazana przez jego iterator nie może zostać zmieniona.
Poniższy kod wyświetla wszystkie wartości obiektu ciągów, używając const_reverse_iterator, zaczynając od ostatniego elementu:
const string str = "vwxyz";
for (String :: const_reverse_iterator q = str.crbegin (); Q <= str.crend(); q++)
Cout << *q << ";
Cout << endl;
Wyjście to:
Z y x w v
Chociaż deklaracja obiektu string. Wynika to z użycia const_reverse_iterator. Nawet gdyby deklaracja była poprzedzona Const, nadal nie skompilowałaby z tego samego powodu. Kod to:
const string str = "vwxyz";
String :: const_reverse_iterator q = str.crbegin ();
Q ++; Q ++;
*q = „a”;
Wniosek
Klasa ciągów nie ma funkcji członka, aby odwrócić ciąg. Jednak ciąg można odwrócić pośrednio, iterację od tyłu do przodu. Zaangażowane funkcje członka to, end (), początek (), rend (), rbegin (), crend () i crbegin (). Zaangażowane iteratory to iterator, reverse_iterator i const_reverse_iterator. Te cechy są łączone w celu uzyskania pośredniego, ale wciąż skutecznego odwrócenia literatu.