IT

벡터에서 서브 벡터를 추출하는 가장 좋은 방법은?

lottoking 2020. 3. 26. 08:30
반응형

벡터에서 서브 벡터를 추출하는 가장 좋은 방법은?


size std::vector()라고 가정 해보십시오 . 0 <= X <= Y <= N-1 인 요소 X부터 Y까지의 복사본으로 구성된 새 벡터를 구성하는 가장 간단한 방법은 무엇입니까? 예를 들어 size의 벡터를 통해 통과 합니다 .myVecNmyVec [100000]myVec [100999]150000

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


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

새로운 벡터를 구성하는 것은 O (N) 연산이지만 실제로 더 좋은 방법은 없습니다.


벡터 생성자를 사용하십시오.

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

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

std::vector(input_iterator, input_iterator)귀하의 경우 여기foo = std::vector(myVec.begin () + 100000, myVec.begin () + 150000); 예를 참조 하십시오


요즘에는 spans 를 사용 합니다! 그래서 당신은 쓸 것입니다 :

#include <gsl/span>

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

와 같은 유형의 요소 1000 개를 가져옵니다 myvec. 자, 이것은 사본아니며 벡터의 데이터를 볼 뿐이 므로주의하십시오. 실제 사본을 원할 경우 다음을 수행 할 수 있습니다.

std::vector<T> new_vec(my_subspan.cbegin(), my_subspan.cend());

노트:


모두 수정하지 않을 경우 (항목이 추가 / 삭제 - 기존 수정하는만큼 당신이 스레딩 문제에주의를 지불로 괜찮습니다)을, 당신은 단순히 주변에 통과 할 수 data.begin() + 100000data.begin() + 101000, 그들이있는 척 begin()하고 end()작은 벡터.

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

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

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


유형 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

M이 서브 벡터의 크기 인 경우 O (M) 성능과 함께 STL 복사사용할 수 있습니다 .


확인. 이것은 꽤 오래된 토론입니다. 그러나 나는 방금 깔끔한 것을 발견했습니다.

slice_array- 이것이 빠른 대안이 될 수 있습니까? 나는 그것을 테스트하지 않았습니다.


선형 시간이 아닌 컬렉션을 투영하는 유일한 방법은 느리게 만드는 것입니다. 결과 "벡터"는 실제로 원래 컬렉션에 위임하는 하위 유형입니다. 예를 들어 Scala의 List#subseq방법은 일정한 시간에 하위 시퀀스를 만듭니다. 그러나 이것은 컬렉션이 변경 불가능하고 기본 언어가 스포츠 가비지 수집 인 경우에만 작동합니다.


당신은 그냥 사용할 수 있습니다 insert

vector<type> myVec { n_elements };

vector<type> newVec;

newVec.insert(newVec.begin(), myVec.begin() + X, myVec.begin() + Y);

다른 사람들을 위해 이것을 늦게 게시합니다. 나는 첫 번째 코더가 지금 끝날 것이라고 확신합니다. 간단한 데이터 유형의 경우 복사가 필요하지 않으며 오래된 C 코드 메소드로 되돌립니다.

std::vector <int>   myVec;
int *p;
// Add some data here and set start, then
p=myVec.data()+start;

그런 다음 포인터 p와 len을 서브 벡터가 필요한 모든 것에 전달하십시오.

notelen은 있어야합니다! len < myVec.size()-start


GSL 라이브러리 array_view / span 이 좋은 옵션 일 수 있습니다.

여기에 하나의 파일 구현도 : array_view .


쉽게 하나 개의 벡터에서 다른 요소를 복사
이 예제에서는 이해하기 쉬운 그것을 만들 쌍의 벡터를 사용하고
`

vector<pair<int, int> > v(n);

//we want half of elements in vector a and another half in vector b
vector<pair<lli, lli> > a(v.begin(),v.begin()+n/2);
vector<pair<lli, lli> > b(v.begin()+n/2, v.end());


//if v = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
//then a = [(1, 2), (2, 3)]
//and b = [(3, 4), (4, 5), (5, 6)]

//if v = [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 7)]
//then a = [(1, 2), (2, 3), (3, 4)]
//and b = [(4, 5), (5, 6), (6, 7)]

'
보시다시피 한 벡터에서 다른 벡터로 요소를 쉽게 복사 할 수 있습니다. 예를 들어 인덱스 10에서 16으로 요소를 복사하려면

vector<pair<int, int> > a(v.begin()+10, v.begin+16);

색인 10의 요소부터 끝의 일부 색인까지 원하는 경우이 경우

vector<pair<int, int> > a(v.begin()+10, v.end()-5);

이것이 도움이되기를 바라며, 마지막 경우를 기억하십시오. v.end()-5 > v.begin()+10


또 다른 옵션 : 예를 들어 생성자를 사용할 수없는 a thrust::device_vector와 a 사이를 이동할 때 유용합니다 thrust::host_vector.

std::vector<T> newVector;
newVector.reserve(1000);
std::copy_n(&vec[100000], 1000, std::back_inserter(newVector));

복잡성이어야 함 O (N)

이것을 상위 Anwer 코드와 결합 할 수 있습니다

vector<T>::const_iterator first = myVec.begin() + 100000;
vector<T>::const_iterator last = myVec.begin() + 101000;
std::copy(first, last, std::back_inserter(newVector));

참고 URL : https://stackoverflow.com/questions/421573/best-way-to-extract-a-subvector-from-a-vector

반응형