2015-01-18 2 views
4

주어진 std :: vector의 일부를 다른 "작은"std :: vector로 대체하는 (덮어 쓰는) 올바른 방법은 무엇일까요? 원본 벡터의 나머지 부분을 변경하지 않고 유지합니다. 또한 원래 벡터에 있었던 것을 귀찮게 할 필요가 없습니다. 더 작은 벡터를 더 이상 유지할 필요가 없습니다. std :: vector의 부분을 small std :: vector로 대체합니다.

내가이 있다고 가정 해 :

std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 }; 
std::vector<int> a = { 1, 2, 3 }; 
std::vector<int> b = { 4, 5, 6, 7, 8 }; 

을 그리고 나는 그것을 달성하고자 :

input = { 1, 2, 3, 4, 5, 6, 7, 8, 99} 

을 할 수있는 올바른 방법은 무엇입니까? I는 같을 것이다

input.replace(input.beginn(), input.beginn()+a.size(), a); 

// 중간재 같은 것을 생각할 : 입력 = {1, 2, 3, 1, 2, 22, 3, 33, 99};

input.replace(input.beginn()+a.size(), input.beginn()+a.size()+b.size(), b); 

표준 방법이 있어야하며 그렇지 않습니까? 이에 대한 내 생각은 지금까지 다음과 같습니다 :

  • 나는 표준을 사용할 수 없습니다 : 벡터 :: 지정은 입력의 모든 요소를 ​​파괴하기위한
  • 표준 : : 벡터 ::와 push_back을 대체 할 것이지만, 입력 확대 -> 내가 원하는 건 아니야

  • std :: vector :: insert는 새로운 요소를 만들고 입력 벡터를 확대하지만 벡터 a.size() + b.size() < = input.size()

  • std :: vector :: swap은 작동하지 않습니다. 거기에 남아 있어야 할 입력의 일부 내용이 있습니다 (예를 들어 마지막 요소) 또한 그 방법으로 B를 추가 할 수 없다.
  • std :: vector :: emplace 또한 input.size를 증가시킨다. 잘

또한 솔루션은 불필요한 지우기 또는 벡터 a 또는 b 값을 다시 작성하여 성능을 낭비하지 않는 것이 좋습니다. 내 벡터는 실제 크기로 매우 커질 것이며 결국 성능에 관한 것입니다.

유능한 도움이 필요하시면 대단히 감사하겠습니다.

+2

['std :: copy'] (http://en.cppreference.com/w/cpp/algorithm/copy)를 찾으십니까? 귀하의 질문을 정확하게 이해한다면 (확실하지 않음) [this] (http://coliru.stacked-crooked.com/a/755867ac783ad0a7)가 귀하가 원하는 것이어야합니다. 그렇다면 알려주세요. 답변으로 게시하겠습니다. –

+0

완전히 이해하지는 못했지만, 내가 겪은 것처럼 보입니다. OutputIt 사본 포함 (InputIt first, InputIt last, OutputIt d_first); 그것은 : 의 의미를 이해할 수 없다 : "d_first = input.beginn ( )"d_first는 복사해서는 안된다. 이 경우에는 [first, last) std :: copy_backward를 사용해야합니다. " – Simeon

답변

6

당신은 std::copy() 이후가 될 것으로 보인다.당신은 또한 다음 사본을 삽입 지점으로 std::copy()에 첫 번째 호출에 의해 반환 된 반복자를 사용할 수 있습니다이 경우, Zyx2000으로

#include <algorithm> // Necessary for `std::copy`... 

// ... 

std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 }; 
std::vector<int> a = { 1, 2, 3 }; 
std::vector<int> b = { 4, 5, 6, 7, 8 };  

std::copy(std::begin(a), std::end(a), std::begin(input)); 
std::copy(std::begin(b), std::end(b), std::begin(input) + a.size()); 

in the comments 노트 : 이것은 당신의 예 (live demo on Coliru)에서 사용하는 것이 방법입니다 :

auto last = std::copy(std::begin(a), std::end(a), std::begin(input)); 
std::copy(std::begin(b), std::end(b), last); 

이 방법은, 임의 접근 반복자가 더 이상 필요하지 않은 - 즉 우리가 표현 std::begin(input) + a.size() 있던 사건이었다.

std::copy()의 처음 두 인수는 복사 할 요소의 원본 범위를 나타냅니다. 세 번째 인수는 대상 컨테이너에서 덮어 쓸 첫 번째 요소에 대한 반복자입니다.

std::copy()을 사용하는 경우 대상 컨테이너가 복사 할 요소의 수를 수용 할만큼 충분히 큰지 확인하십시오.

또한 소스와 대상 범위는 인터리브하지 않아야합니다.

+2

'std :: begin (input) + a.size()'를'std :: copy'에 대한 첫 번째 호출의 반환 값으로 대체함으로써보다 일반적인 코드를 만들 수 있습니다. 그런 다음 반복기가 임의 액세스 반복자가 아닌 경우에도 작동합니다 ([Example] (http://coliru.stacked-crooked.com/a/25c25acf94ad0807)). –

+0

@ Zyx2000 : 맞아, 좋은 지적이야! –

0

이 시도 :

#include <iostream> 
#include <vector> 
#include <algorithm> 

int main() { 
    std::vector<int> input = { 0, 0, 1, 1, 2, 22, 3, 33, 99 }; 
    std::vector<int> a = { 1, 2, 3 }; 
    std::vector<int> b = { 4, 5, 6, 7, 8 }; 

    std::set_union(a.begin(), a.end(), b.begin(), b.end(), input.begin()); 

    for (std::vector<int>::const_iterator iter = input.begin(); 
      iter != input.end(); 
      ++iter) 
    { 
     std::cout << *iter << " "; 
    } 

    return 0; 
} 

그것은 출력 :

1 2 3 4 5 6 7 8 99 
+0

아직 100 % 확신 할 수는 없지만 올바른 대답은 아닌 것 같습니다. 나는 a와 b가 항상 orderd가 아니며 머무를 필요가있는 입력 요소가 이전의 것보다 큽니다. 또한 필자는 아주 큰 크기의 벡터를 사용하기 때문에 필기 및 memmoryallocation을 최소화하고 싶습니다. 입력을 재사용하면 추가 메모리 할당이 필요하지 않습니다. 그 이유는 출력이 입력과 정확하게 동일한 크기를 가지기 때문입니다. – Simeon

+0

그래, 문제 없습니다. 나는이 대답을 어쨌든 남겨 둘 것이다 .... 내가 downvotes를 얻지 않는 한 ... 코멘트 주셔서 감사합니다! – jpo38