The most efficient way to move a row / column in 2D std :: vector

I am creating a C ++ game application. I have a map presented as a 2-dimensional std::vector object of Tile objects.

I need to update this map when moving a player. From the server application, I get a row or column with a new part of the global map, which should be placed on the client’s local map, for example:

enter image description here

In Figure 1, a local map before the player moves. The top line is filled with objects 1, in the center with 2 and bottom with 0. Now, when the player goes up, I get a new top line filled with objects 3, and all the rest should be omitted, and the previous bottom line should disappear.

I can do this only by moving the required objects to for loops, but I thought that if there is some kind of algorithm in the standard library or preferred by many, an effective way to achieve this kind of modifications.

EDIT:

Sorry, I did not understand that there would be a difference between performing this operation for a row and a column, but there really is. Therefore, I also edited my header, because sometimes I also need to do this for a column.

+7
source share
5 answers

You might want to implement an iterator and not move vector elements at all. Just define a variable for the top row index (on the screen), then use the modulo operator to iterate over all rows (so that only 000 rows should be overwritten with 333, and the top row index will be 2 instead of 0). This algorithm is efficient (only as much memory as it writes as needed) and can be used to scroll in any direction:

  • Move up: decrease the index of the top line (line number of the mod), change the last line
  • Move down: increase the index of the top line (line number of the mod), change the first line
  • Move to the left: decrease the index of the left column (model model number), change the last column
  • Moving to the right: increase the index of the left column (model model number), change the first column.
+6
source

There are two standard containers that immediately come to your mind when you need a quick insert / delete at both ends: std::deque and std::list . However, they have their own specific requirements and limitations.

If you're stuck in a vector, you can use C ++ 11's move semantics, which will allow you to efficiently move objects rather than copy them, or as @WebMonster mentions that you can use some kind of circular index in your buffer, which completely excludes the need to move / copy.

Given your requirements and assuming they are complete, I will probably go to @WebMonster's solution, which is the most efficient. Edit: Now that your requirements have changed, and you also need to scroll through the columns, its solution to the “circular index” is definitely the way to go.

+3
source

You can use std :: swap, which is specialized for vectors and is efficient, since two vectors only require a few pointer swaps. Alternatively, you can use std :: rotate, but I'm not sure if it uses the swap technique.

Unfortunately, this will only work if you have a row vector, and you need to shift rows, or you have a column vector, and you need to shift columns. It seems that for both operations to work effectively, you need to use a more complex data structure.

+2
source

I would suggest increasing the matrix .

+2
source

A possible way would be to use:

std::std::swap_ranges() to move existing lines in your 2D std::vector

and

std::transform() to change the string to be replaced with new values.

0
source

All Articles