Celem jest uzyskanie dostępu do „n-tego” elementu wektora łańcuchów zamiast operatora [] lub metody „at”. Z tego, co rozumiem, iteratory mogą być używane do poruszania się po kontenerach, ale nigdy wcześniej nie korzystałem z iteratorów, a to, co czytam, jest mylące.
Byłbym wdzięczny, gdyby ktoś mógł mi udzielić informacji, jak to osiągnąć. Dziękuję Ci.
Odpowiedzi:
Musisz skorzystać z metody
begin
i klasy, która zwraca iterator odnoszący się odpowiednio do pierwszego i ostatniego elementu.end
vector
źródło
std::vector
ma iteratory dostępu swobodnego.std::advance(it, n)
. Jest zdefiniowany, aby robić dokładnie to, co chcesz, i automatycznie użyje,it + n
jeśli iterator jest oznaczony jako losowy dostęp lub zrobi pętlę, jeśli będzie to konieczne.Zazwyczaj iteratory są używane do uzyskiwania dostępu do elementów kontenera w sposób liniowy; jednakże dzięki „iteratorom dostępu swobodnego” możliwy jest dostęp do dowolnego elementu w taki sam sposób, jak
operator[]
.Aby uzyskać dostęp do dowolnych elementów w wektorze
vec
, możesz użyć:Poniżej znajduje się przykład typowego wzorca dostępu (wcześniejsze wersje C ++):
Zaletą korzystania z iteratora jest to, że ten sam wzorzec można zastosować w innych kontenerach :
Z tego powodu bardzo łatwo jest stworzyć kod szablonu, który będzie działał tak samo niezależnie od typu kontenera . Kolejną zaletą iteratorów jest to, że nie zakładają one, że dane są rezydentne w pamięci; na przykład można stworzyć iterator do przodu, który może czytać dane ze strumienia wejściowego lub po prostu generuje dane w locie (np. generator zakresu lub liczb losowych).
Inna opcja przy użyciu
std::for_each
i lambd:Od C ++ 11 możesz użyć,
auto
aby uniknąć określania bardzo długiej, skomplikowanej nazwy typu iteratora, jak widać wcześniej (lub nawet bardziej złożonej):Ponadto istnieje prostszy wariant dla każdego:
I wreszcie jest miejsce, w
std::accumulate
którym musisz uważać, czy dodajesz liczby całkowite, czy zmiennoprzecinkowe.źródło
W C ++ - 11 możesz:
Zobacz tutaj warianty: https://en.cppreference.com/w/cpp/language/range-for
źródło
7.5.0
na Ubuntu 18.04 i działa w przypadku tablicy w ten sam sposób.Iteratory wektora to iteratory o dostępie swobodnym, co oznacza, że wyglądają i działają jak zwykłe wskaźniki.
Możesz uzyskać dostęp do n-tego elementu, dodając n do iteratora zwróconego przez
begin()
metodę kontenera lub możesz użyć operatora[]
.Alternatywnie możesz użyć funkcji zaawansowanej, która działa ze wszystkimi rodzajami iteratorów. (Trzeba by się zastanowić, czy naprawdę chcesz wykonać „dostęp losowy” z iteratorami o dostępie innym niż losowy, ponieważ może to być kosztowne).
źródło
advance
dla iteratorów o swobodnym dostępie lub iteratorów o nieznanej kategorii, ponieważ w tym przypadku gwarantujemy, że będą działać w stałym czasie. Dlatego też iteratory zdefiniowane przez użytkownika powinny być poprawnie oznakowane.advance
jest to naprawdę denerwujące w użyciu (ze względu na użycie parametru out), jeśli wiesz, że masz do czynienia z iteratorami o swobodnym dostępie. Poleciłbym tylko w kodzie ogólnym, a jeśli nie jest używany często (jeśli algorytm nie obsługuje dobrze iteratorów o dostępie innym niż losowy, niech tak będzie - na przykładstd::sort
mógłby posortować,std::list
ale tak nie jest, ponieważ byłby absurdalnie nieefektywny ).operator+
. Ale pytanie dotyczyło bezpośrednio wektora, więc nie ma nic złego w pierwszej części twojej odpowiedzi. Pomyślałem po prostu, że druga część może oznaczać „nie można używać zaawansowanych z iteratorami o swobodnym dostępie, nawet jeśli chcesz” komuś, kto nigdyadvance
wcześniej nie widział .Vector
powinna być pisana małymi literamiOto przykład dostępu do
ith
indeksu astd::vector
przy użyciustd::iterator
pętli wewnątrz pętli, która nie wymaga inkrementacji dwóch iteratorów.Bez pętli for
i
at
metodą:źródło