5

I have a vector of bytes (std::vector ): [1,1,1,9,9,9,1,1,1]

I want to replace bytes 3-6 with unknown length of bytes (I'll know at run time obv.). So the length of the vector may grow, shirk or stay the same. But I know the start point and end point of the bytes I want to replace.

I can do this using erase or insert to adjust the size, then a loop around the new data onto the old data.

std::replace does a search and the replaces matching the bytes, whereas I know what bytes I want to replace. And std::replace seem to only replace one element. I want to replace with blob of data.

Surely there is a std function that can do this 'neatly'? (and I'll call you Shirely if I want to).

TinyRacoon
  • 4,655
  • 2
  • 23
  • 22
  • How much do you know at compile time? Do you know the original contents of the vector? Or least its size? Or at least the range you need to remove before inserting? –  Mar 13 '17 at 12:20

3 Answers3

4

If the values are all the same and you know the interval you want to replace is within the vector, use std::fill:

std::fill(v.begin() + 3, v.begin() + 6, 9);

This line will replace elements 3-6 on the vector v with value 9.

If the values you want to put are not all the same, use std::copy instead (you need to be sure that the replacement fits into the vector):

std::copy(replacement.begin(), replacement.end(), v.begin() + 3); 

This replaces contents of the vector v starting at position 3 with contents of replacement.

If you are not sure about the size of the vector, you may correct the size first:

v.resize(6);
Ilya Popov
  • 3,765
  • 1
  • 17
  • 30
3

std::vector::insert can insert ranges, so just erase the existing elements and insert the new ones.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Yes. My first thought. I just would like to be more efficient. And not delete space that I might need afterwards. Save a lot of data moving about. – TinyRacoon Mar 13 '17 at 11:59
  • 2
    You could do a combination of `std::copy` (to copy the portion of the range that overlaps with what's in the vector already) and either `erase` or `insert` (to adjust the vector's size appropriately). – Jason R Mar 13 '17 at 12:09
  • 3
    Do in two steps, (1) insert **or** erase elements to make the final length correct (2) copy the elements that were not copied at step 1. – n. m. could be an AI Mar 13 '17 at 12:10
1

Short answer: there's no ultimate solution for your problem unless we get more details from you

Long answer: From what I see here, it sounds to me that std::vector is a very bad choice for this. std::vector is contiguous in memory (starting from C++03), and what you're doing has two possible outcomes:

  1. You'll keep the same size of the container, and vectors are perfect for this
  2. You'll change the size of the vector from the middle, and vector's are horrible at this! But, std::deque is a middle grounds for this. The reason for this is here. It exactly supports doing what you want to do in (almost) constant time, and provides element access at constant time.

The question you need to answer to decide which way to go is: How often do you need to make a replacement that will change the size of the vector compared to one that won't? Only if the number changes in the size of the vector are very small, std::vector would be a good choice. Otherwise, you should consider switching to std::deque.

Is there something in the standard that does that replacement for me?

The standard provides all the tools to do this as efficient as possible with a function that you write yourself. Erase (if necessary), then insert. It's as simple as that. Keep in mind two things:

  1. Erase only the difference, don't erase the whole thing you want to replace, the former would perform better
  2. Always consider the special case if the part you want to remove has a size equal to the array you want to place in. In that case, don't remove or insert anything. This saves a lot in performance.
Community
  • 1
  • 1
The Quantum Physicist
  • 24,987
  • 19
  • 103
  • 189