목표는 [] 연산자 나 "at"메서드 대신 문자열 벡터의 "n 번째"요소에 액세스하는 것입니다. 내가 이해하는 바에 따르면 반복기를 컨테이너를 탐색하는 데 사용할 수 있지만 이전에는 반복기를 사용한 적이 없으며 읽고있는 내용이 혼란 스럽습니다.
누구든지 이것을 달성하는 방법에 대한 정보를 줄 수 있다면 감사하겠습니다. 감사합니다.
목표는 [] 연산자 나 "at"메서드 대신 문자열 벡터의 "n 번째"요소에 액세스하는 것입니다. 내가 이해하는 바에 따르면 반복기를 컨테이너를 탐색하는 데 사용할 수 있지만 이전에는 반복기를 사용한 적이 없으며 읽고있는 내용이 혼란 스럽습니다.
누구든지 이것을 달성하는 방법에 대한 정보를 줄 수 있다면 감사하겠습니다. 감사합니다.
답변:
첫 번째 요소와 마지막 요소를 각각 참조하는 반복기를 반환하는 클래스 의 begin
및 end
메서드를 사용해야 vector
합니다.
using namespace std;
vector<string> myvector; // a vector of stings.
// push some strings in the vector.
myvector.push_back("a");
myvector.push_back("b");
myvector.push_back("c");
myvector.push_back("d");
vector<string>::iterator it; // declare an iterator to a vector of strings
int n = 3; // nth element to be found.
int i = 0; // counter.
// now start at from the beginning
// and keep iterating over the element till you find
// nth element...or reach the end of vector.
for(it = myvector.begin(); it != myvector.end(); it++,i++ ) {
// found nth element..print and break.
if(i == n) {
cout<< *it << endl; // prints d.
break;
}
}
// other easier ways of doing the same.
// using operator[]
cout<<myvector[n]<<endl; // prints d.
// using the at method
cout << myvector.at(n) << endl; // prints d.
std::vector
랜덤 액세스 반복자가 있다는 사실을 놓친다 .
std::advance(it, n)
입니다. 원하는 것을 정확히 수행하도록 정의되어 it + n
있으며 반복자가 임의 액세스로 태그가 지정되면 자동으로 사용하고 필요한 경우 루프를 수행합니다.
일반적으로 반복기는 선형 방식으로 컨테이너의 요소에 액세스하는 데 사용됩니다. 그러나 "무작위 액세스 반복자"를 사용하면 다음과 같은 방식으로 모든 요소에 액세스 할 수 있습니다.operator[]
.
벡터의 임의 요소에 액세스 하려면 vec
다음을 사용할 수 있습니다.
vec.begin() // 1st
vec.begin()+1 // 2nd
// ...
vec.begin()+(i-1) // ith
// ...
vec.begin()+(vec.size()-1) // last
다음은 일반적인 액세스 패턴 의 예입니다 (이전 버전의 C ++).
int sum = 0;
using Iter = std::vector<int>::const_iterator;
for (Iter it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
반복기 사용의 장점은 다른 컨테이너에 동일한 패턴을 적용 할 수 있다는 것입니다 .
sum = 0;
for (Iter it = lst.begin(); it!=lst.end(); ++it) {
sum += *it;
}
이러한 이유로 컨테이너 유형에 관계없이 동일하게 작동하는 템플릿 코드를 만드는 것은 정말 쉽습니다. . 반복자의 또 다른 장점은 데이터가 메모리에 상주한다고 가정하지 않는다는 것입니다. 예를 들어, 입력 스트림에서 데이터를 읽을 수있는 순방향 반복기를 만들거나 단순히 즉석에서 데이터를 생성하는 (예 : 범위 또는 난수 생성기) 만들 수 있습니다.
std::for_each
및 람다를 사용하는 또 다른 옵션 :
sum = 0;
std::for_each(vec.begin(), vec.end(), [&sum](int i) { sum += i; });
C ++ 11부터는 auto
이전에 본 것처럼 (또는 훨씬 더 복잡한) 반복자의 매우 길고 복잡한 유형 이름을 지정하지 않도록 사용할 수 있습니다 .
sum = 0;
for (auto it = vec.begin(); it!=vec.end(); ++it) {
sum += *it;
}
또한 더 간단한 for-each 변형이 있습니다.
sum = 0;
for (auto value : vec) {
sum += value;
}
마지막으로 std::accumulate
정수 또는 부동 소수점 숫자를 추가 할 때주의해야 할 부분도 있습니다.
C ++-11에서는 다음을 수행 할 수 있습니다.
std::vector<int> v = {0, 1, 2, 3, 4, 5};
for (auto i : v)
{
// access by value, the type of i is int
std::cout << i << ' ';
}
std::cout << '\n';
변형은 여기를 참조하십시오 : https://en.cppreference.com/w/cpp/language/range-for
7.5.0
Ubuntu 18.04 에서 gcc로 시도 했으며 동일한 방식으로 배열에서 작동합니다.
Vector의 반복기는 랜덤 액세스 반복기이므로 일반 포인터처럼 보이고 느껴집니다.
컨테이너의 begin()
메서드 에서 반환 된 반복기에 n을 추가하여 n 번째 요소에 액세스 하거나 operator를 사용할 수 있습니다 []
.
std::vector<int> vec(10);
std::vector<int>::iterator it = vec.begin();
int sixth = *(it + 5);
int third = *(2 + it);
int second = it[1];
또는 모든 종류의 반복자와 함께 작동 하는 고급 기능을 사용할 수 있습니다 . (비 랜덤 액세스 반복기를 사용하여 "무작위 액세스"를 수행 할 것인지 여부를 고려해야합니다. 비용이 많이들 수 있기 때문입니다.)
std::vector<int> vec(10);
std::vector<int>::iterator it = vec.begin();
std::advance(it, 5);
int sixth = *it;
advance
랜덤 액세스 반복자 또는 알 수없는 범주의 반복자에도 사용할 수 있습니다 .이 경우 일정한 시간에 작동하도록 보장되기 때문입니다. 이것이 사용자 정의 반복기가 올바르게 태그되어야하는 이유입니다.
advance
랜덤 액세스 반복자를 다루는 것을 안다면 (out 매개 변수 사용으로 인해) 사용하기가 정말 짜증납니다. 단지 일반적인 코드에서 추천 할 것, 그리고 (많이 사용하지 않을 경우 알고리즘이 잘 아닌 임의 접근 반복자를 지원하지 않는 경우, 그래서 수 - 예를 들어, std::sort
수 를 정렬 std::list
하지만 그것이 엄청나게 비효율적하지 않기 때문에 ).
operator+
. 그러나 질문은 명시 적으로 벡터에 관한 것이기 때문에 답변의 첫 번째 부분에는 잘못된 것이 없습니다. 두 번째 부분은 "원한다고해도 랜덤 액세스 반복기와 함께 advance를 사용할 수 없다"는 것을 advance
전에 본 적이없는 사람에게 암시 할 수 있다고 생각했습니다 .
Vector
소문자되어야
다음은 두 반복자를 증가시킬 필요가없는 루프 내에서 사용하여 의 ith
인덱스 에 액세스하는 예입니다 .std::vector
std::iterator
std::vector<std::string> strs = {"sigma" "alpha", "beta", "rho", "nova"};
int nth = 2;
std::vector<std::string>::iterator it;
for(it = strs.begin(); it != strs.end(); it++) {
int ith = it - strs.begin();
if(ith == nth) {
printf("Iterator within a for-loop: strs[%d] = %s\n", ith, (*it).c_str());
}
}
for 루프없이
it = strs.begin() + nth;
printf("Iterator without a for-loop: strs[%d] = %s\n", nth, (*it).c_str());
및 사용 at
방법 :
printf("Using at position: strs[%d] = %s\n", nth, strs.at(nth).c_str());