끝에서 시작까지 C ++ 벡터 반복
끝에서 시작까지 벡터를 반복 할 수 있습니까?
for (vector<my_class>::iterator i = my_vector.end();
i != my_vector.begin(); /* ?! */ ) {
}
또는 다음과 같은 경우에만 가능합니다.
for (int i = my_vector.size() - 1; i >= 0; --i) {
}
가장 좋은 방법은 다음과 같습니다.
for (vector<my_class>::reverse_iterator i = my_vector.rbegin();
i != my_vector.rend(); ++i ) {
}
rbegin()/ rend()특별히 그 목적을 위해 설계되었습니다. (예, a를 증가 reverse_interator시키면 뒤로 이동합니다.)
이제 이론적으로는 방법 ( begin()/ end()& 사용 --i)이 작동 할 것입니다. std::vector반복기는 양방향이지만 end()마지막 요소가 아니라는 점을 기억 하십시오. 마지막 요소를 넘어선 요소이므로 먼저 감소해야합니다. 도달하면 완료 begin()되지만 여전히 처리를해야합니다.
vector<my_class>::iterator i = my_vector.end();
while (i != my_vector.begin())
{
--i;
/*do stuff */
}
업데이트 : 나는 for()루프를 루프로 다시 쓰는 데 너무 공격적이었습니다 while(). (중요한 부분은이 --i시작 부분에 있다는 것 입니다.)
C ++ 11이있는 경우 auto.
for (auto it = my_vector.rbegin(); it != my_vector.rend(); ++it)
{
}
폐쇄-개방 범위를 통한 역 반복을위한 잘 확립 된 "패턴"은 다음과 같습니다.
// Iterate over [begin, end) range in reverse
for (iterator = end; iterator-- != begin; ) {
// Process `*iterator`
}
또는 원하는 경우
// Iterate over [begin, end) range in reverse
for (iterator = end; iterator != begin; ) {
--iterator;
// Process `*iterator`
}
이 패턴은 예를 들어 부호없는 인덱스를 사용하여 배열을 역 인덱싱하는 데 유용합니다.
int array[N];
...
// Iterate over [0, N) range in reverse
for (unsigned i = N; i-- != 0; ) {
array[i]; // <- process it
}
(이 패턴에 익숙하지 않은 사람들 은 서명되지 않은 유형이 역 인덱싱에 "사용할 수 없다"고 잘못 믿기 때문에 특히 배열 인덱싱에 부호있는 정수 유형을 사용해야한다고 주장합니다.)
"슬라이딩 포인터"기술을 사용하여 배열을 반복하는 데 사용할 수 있습니다.
// Iterate over [array, array + N) range in reverse
for (int *p = array + N; p-- != array; ) {
*p; // <- process it
}
또는 일반 (역방향 아님) 반복기를 사용하여 벡터에 대한 역 반복에 사용할 수 있습니다.
for (vector<my_class>::iterator i = my_vector.end(); i-- != my_vector.begin(); ) {
*i; // <- process it
}
사용자 rend() / rbegin()반복자 :
for (vector<myclass>::reverse_iterator it = myvector.rbegin(); it != myvector.rend(); it++)
template<class It>
std::reverse_iterator<It> reversed( It it ) {
return std::reverse_iterator<It>(std::forward<It>(it));
}
그때:
for( auto rit = reversed(data.end()); rit != reversed(data.begin()); ++rit ) {
std::cout << *rit;
또는 C ++ 14에서 다음을 수행하십시오.
for( auto rit = std::rbegin(data); rit != std::rend(data); ++rit ) {
std::cout << *rit;
C ++ 03 / 11에서 대부분의 표준 컨테이너에는 .rbegin()및 .rend()메서드도 있습니다.
마지막 backwards으로 다음과 같이 범위 어댑터 를 작성할 수 있습니다 .
namespace adl_aux {
using std::begin; using std::end;
template<class C>
decltype( begin( std::declval<C>() ) ) adl_begin( C&& c ) {
return begin(std::forward<C>(c));
}
template<class C>
decltype( end( std::declval<C>() ) ) adl_end( C&& c ) {
return end(std::forward<C>(c));
}
}
template<class It>
struct simple_range {
It b_, e_;
simple_range():b_(),e_(){}
It begin() const { return b_; }
It end() const { return e_; }
simple_range( It b, It e ):b_(b), e_(e) {}
template<class OtherRange>
simple_range( OtherRange&& o ):
simple_range(adl_aux::adl_begin(o), adl_aux::adl_end(o))
{}
// explicit defaults:
simple_range( simple_range const& o ) = default;
simple_range( simple_range && o ) = default;
simple_range& operator=( simple_range const& o ) = default;
simple_range& operator=( simple_range && o ) = default;
};
template<class C>
simple_range< decltype( reversed( adl_aux::adl_begin( std::declval<C&>() ) ) ) >
backwards( C&& c ) {
return { reversed( adl_aux::adl_end(c) ), reversed( adl_aux::adl_begin(c) ) };
}
이제 다음과 같이 할 수 있습니다.
for (auto&& x : backwards(ctnr))
std::cout << x;
꽤 예쁘다고 생각합니다.
역방향 반복기와 루프를 사용 rbegin()하여rend()
나는 Yakk-Adam Nevraumont의 대답 끝에있는 역방향 반복기를 좋아하지만 내가 필요한 것에 대해 복잡해 보였으므로 다음과 같이 썼습니다.
template <class T>
class backwards {
T& _obj;
public:
backwards(T &obj) : _obj(obj) {}
auto begin() {return _obj.rbegin();}
auto end() {return _obj.rend();}
};
다음과 같은 일반 반복기를 사용할 수 있습니다.
for (auto &elem : vec) {
// ... my useful code
}
반대로 반복하려면 다음과 같이 변경하십시오.
for (auto &elem : backwards(vec)) {
// ... my useful code
}
다음은 각 구문에 대한 사용을 허용하고 C ++ 14 표준 라이브러리에만 의존하는 매우 간단한 구현입니다.
namespace Details {
// simple storage of a begin and end iterator
template<class T>
struct iterator_range
{
T beginning, ending;
iterator_range(T beginning, T ending) : beginning(beginning), ending(ending) {}
T begin() const { return beginning; }
T end() const { return ending; }
};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// usage:
// for (auto e : backwards(collection))
template<class T>
auto backwards(T & collection)
{
using namespace std;
return Details::iterator_range(rbegin(collection), rend(collection));
}
이것은 rbegin () 및 rend ()를 제공하는 것뿐만 아니라 정적 배열에서도 작동합니다.
std::vector<int> collection{ 5, 9, 15, 22 };
for (auto e : backwards(collection))
;
long values[] = { 3, 6, 9, 12 };
for (auto e : backwards(values))
;
이 코드 사용
//print the vector element in reverse order by normal iterator.
cout <<"print the vector element in reverse order by normal iterator." <<endl;
vector<string>::iterator iter=vec.end();
--iter;
while (iter != vec.begin())
{
cout << *iter << " ";
--iter;
}
As I don't want to introduce alien Mars new syntax whatever, and I simply want to build up on existing primitives, the below snippets seems to work:
#include <vector>
#include <iostream>
int main (int argc,char *argv[])
{
std::vector<int> arr{1,2,3,4,5};
std::vector<int>::iterator it;
for (it = arr.begin(); it != arr.end(); it++) {
std::cout << *it << " ";
}
std::cout << "\n************\n";
for (it = arr.end() - 1; it != arr.begin()-1;it--) {
std::cout << *it << " ";
}
return 0;
}
참고URL : https://stackoverflow.com/questions/3610933/iterating-c-vector-from-the-end-to-the-begin
'Programing' 카테고리의 다른 글
| Swift에서 Int를 기반으로 UITableView의 특정 행 새로 고침 (0) | 2020.10.23 |
|---|---|
| 사용자 지정 SSL 인증서 (AWS IAM에 저장 됨)를 선택할 수 없습니다. (0) | 2020.10.23 |
| WatiN 오류로 어셈블리를로드 할 수 없습니다. (0) | 2020.10.23 |
| jQuery를 사용하지 않는 경험적 기술적 이유는 무엇입니까? (0) | 2020.10.23 |
| android.jar에 소스를 첨부하는 방법 (0) | 2020.10.23 |