c++ vector 비우기




벡터에서 서브 벡터를 추출하는 가장 좋은 방법은 무엇입니까? (9)

크기가 N std::vector ( myVec 이라고 myVec )를 가정 해 보겠습니다. 0 ~ = X <= Y <= N-1 인 요소 X ~ Y의 복사본으로 구성된 새 벡터를 만드는 가장 간단한 방법은 무엇입니까? 예를 들어, 크기가 150000 벡터에서 myVec [100000] 부터 myVec [100999] 입니다.

이 작업을 벡터로 효율적으로 수행 할 수 없다면 대신 사용해야하는 다른 STL 데이터 유형이 있습니까?


M이 서브 벡터의 크기 일 때 O (M) 성능으로 STL 카피 를 사용할 수 있습니다.


귀하의 경우 std::vector(input_iterator, input_iterator) , foo = std::vector(myVec.begin () + 100000, myVec.begin () + 150000); 예를 들어 here 참조 here


당신은 어떤 형식 std::vector<...> myVec 언급하지 않았다,하지만 포인터를 포함하지 않는 단순한 형식 또는 구조체 / 클래스 및 최상의 효율성을 원하는 경우 다음 직접 메모리를 할 수 있습니다 복사 (나는 다른 답변보다 빠를 것이라고 생각합니다). 다음은 std::vector<type> myVec 대한 일반적인 예입니다.이 경우 typeint .

typedef int type; //choose your custom type/struct/class
int iFirst = 100000; //first index to copy
int iLast = 101000; //last index + 1
int iLen = iLast - iFirst;
std::vector<type> newVec;
newVec.resize(iLen); //pre-allocate the space needed to write the data directly
memcpy(&newVec[0], &myVec[iFirst], iLen*sizeof(type)); //write directly to destination buffer from source buffer

두 항목 모두 수정하지 않을 경우 (항목을 추가 / 삭제하지 않고 기존 항목을 수정하는 것이 스레드 문제에주의를 기울이는 한 괜찮습니다.) 단순히 data.begin() + 100000data.begin() + 101000 이라고 가정하고 더 작은 벡터의 begin()end() 인 것처럼 가장합니다.

또는 벡터 저장이 연속적으로 보장되므로 1000 개의 항목 배열을 전달할 수 있습니다.

T *arrayOfT = &data[0] + 100000;
size_t arrayOfTLength = 1000;

이 두 기술 모두 일정한 시간이 걸리지 만 데이터 길이가 늘어나지 않아 재 할당이 발생합니다.


벡터 생성자 만 사용하면됩니다.

std::vector<int>   data();
// Load Z elements into data so that Z > Y > X

std::vector<int>   sub(&data[100000],&data[101000]);

선형 시간이 아닌 컬렉션을 영사하는 유일한 방법은 느리게 수행하는 것입니다. 결과 "벡터"는 실제로 원래 컬렉션에 위임하는 하위 유형입니다. 예를 들어, Scala의 List#subseq 메소드는 상수 시간에 서브 시퀀스를 생성합니다. 그러나 이것은 컬렉션이 변경 가능하지 않고 기본 언어가 가비지 컬렉션을 사용하는 경우에만 작동합니다.


어쩌면 GSL 라이브러리의 array_view/span 이 좋은 옵션 일 것입니다.

다음은 하나의 파일 구현 인 array_view 입니다.


요즘 우리는 span 을 사용 span ! 그래서 당신은 다음과 같이 쓸 것입니다.

#include <gsl/span>

...
auto start_pos = 100000;
auto length = 1000;
auto my_subspan = gsl::make_span(myvec).subspan(start_pos, length);

myvec 와 동일한 유형의 1000 개의 요소 범위를 가져옵니다. 자, 이것은 복사본아니며 단지 벡터의 데이터 뷰일뿐 입니다. 따라서주의하십시오. 실제 사본이 필요한 경우 다음을 수행 할 수 있습니다.

std::vector<T> new_vec(my_subspan.begin(), my_subspan.end());

노트:


vector<T>::const_iterator first = myVec.begin() + 100000;
vector<T>::const_iterator last = myVec.begin() + 101000;
vector<T> newVec(first, last);

새로운 벡터를 만드는 것은 O (N) 연산이지만 실제로는 더 좋은 방법은 아닙니다.







range