벡터에서 서브 벡터를 추출하는 가장 좋은 방법은?
size std::vector
()라고 가정 해보십시오 . 0 <= X <= Y <= N-1 인 요소 X부터 Y까지의 복사본으로 구성된 새 벡터를 구성하는 가장 간단한 방법은 무엇입니까? 예를 들어 size의 벡터를 통해 통과 합니다 .myVec
N
myVec [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);
예를 참조 하십시오
요즘에는 span
s 를 사용 합니다! 그래서 당신은 쓸 것입니다 :
#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());
노트:
gsl
가이드 라인 지원 라이브러리를 나타냅니다. 에 대한 자세한 내용은 http://www.modernescpp.com/index.php/c-core-guideline-the-guidelines-support-library를gsl
참조 하십시오 .- 의 구현에
gsl
대해서는 https://github.com/Microsoft/GSL을 참조하십시오. - C ++ 20은의 구현을 제공합니다
span
. 당신이 사용하는 것이std::span
및#include <span>
보다는#include <gsl/span>
. - 범위에 대한 자세한 내용은 "범위"란 무엇이며 언제 사용해야합니까?를 참조하십시오.
std::vector
gazillion 생성자가 있으므로 사용하지 않으려는 생성기에 빠지기 쉽기 때문에 조심하십시오.
모두 수정하지 않을 경우 (항목이 추가 / 삭제 - 기존 수정하는만큼 당신이 스레딩 문제에주의를 지불로 괜찮습니다)을, 당신은 단순히 주변에 통과 할 수 data.begin() + 100000
와 data.begin() + 101000
, 그들이있는 척 begin()
하고 end()
작은 벡터.
또는 벡터 스토리지가 연속적으로 보장되므로 1000 개의 항목 배열을 전달할 수 있습니다.
T *arrayOfT = &data[0] + 100000;
size_t arrayOfTLength = 1000;
이 두 기술 모두 일정한 시간이 걸리지 만 데이터 길이가 늘어나지 않아 재 할당이 트리거되어야합니다.
유형 std::vector<...> myVec
이 무엇인지 언급 하지 않았지만 포인터가 포함되지 않은 간단한 유형 또는 구조체 / 클래스이고 최상의 효율성을 원한다면 직접 메모리 복사를 수행 할 수 있습니다. 다른 답변 제공). 이 경우 일반적인 std::vector<type> myVec
위치 는 다음과 같습니다 .type
int
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
'IT' 카테고리의 다른 글
ActiveRecord의 부동 대 소수 (0) | 2020.03.26 |
---|---|
ArrayList.clear ()와 ArrayList.removeAll ()의 차이점은 무엇입니까? (0) | 2020.03.26 |
다른 스크립트에서 스크립트를 호출하는 가장 좋은 방법은 무엇입니까? (0) | 2020.03.26 |
numpy.array 모양 (R, 1)과 (R,)의 차이점 (0) | 2020.03.26 |
하위 디렉토리에 하위 모듈을 추가하려면 어떻게합니까? (0) | 2020.03.26 |