remove the last element of a vector
You can use negative offsets in head
(or tail
), so head(x, -1)
removes the last element:
R> head( 1:4, -1)
[1] 1 2 3
R>
This also saves an additional call to length()
.
Edit: As pointed out by Jason, this approach is actually not faster. Can't argue with empirics. On my machine:
R> x <- rnorm(1000)
R> microbenchmark( y <- head(x, -1), y <- x[-length(x)], times=10000)
Unit: microseconds
expr min lq median uq max
1 y <- head(x, -1) 29.412 31.0385 31.713 32.578 872.168
2 y <- x[-length(x)] 14.703 15.1150 15.565 15.955 706.880
R>
Segmentation fault on erasing the last element from the vector C++
The problem is that std::vector::end returns an iterator to the element following the last element of the container, not to the last element.
What you want should be
vec.erase(vec.end() - 1); // trying to erase the last element of vec
Remove last n elements of vectorint in O(1) complexity C++?
The C++ standard (I believe) says that the cost of removing k items from the end of a std::vector
must have time complexity O(k), but that's an upper bound on the amount of work done, not a lower bound.
The C++ compiler, when generating code for std::vector<int>::erase
, can inspect the types and realize that there's no need to do any per-element work when removing int
s; it can just adjust the logical size of the std::vector
and call it a day. In fact, it looks like g++, with optimization turned on, does just that. The generated assembly here doesn't involve any loops and simply changes the size of the std::vector
.
If you don't want to rely on the compiler to do this, another option would be to store your own separate size variable and then just "pretend" that you've removed items from the std::vector
by never using them again. That takes time O(1).
Hope this helps!
taking the last element of a vector and moving it to another vector
You are passing the vectors by value, so you are acting on copies of the vectors, not on the original vectors. You need to pass the vectors by reference instead.
Also, you said you wanted to move the last element, but you are actually moving the first element instead. And you are not removing the element from the old vector.
Also, there is no need to use std::move()
with raw pointers. Why are you using ball*
at all? You should be using std::unique_ptr<ball>
instead.
Try something more like this:
void move(std::vector<ball*> &ball_box, std::vector<ball*> &n_ball_box)
{
ball* b = ball_box.back();
ball_box.pop_back();
n_ball_box.push_back(b);
}
If you really want to move the first element, then it would look like this instead:
void move(std::vector<ball*> &ball_box, std::vector<ball*> &n_ball_box)
{
ball* b = ball_box.front();
ball_box.erase(ball_box.begin());
n_ball_box.push_back(b);
}
That said, if you switch to std::unique_ptr<ball>
, then it would look more like this:
using ball_ptr = std::unique_ptr<ball>;
void move(std::vector<ball_ptr> &ball_box, std::vector<ball_ptr> &n_ball_box)
{
ball_ptr b = std::move(ball_box.back());
ball_box.pop_back();
/* or:
ball_ptr b = std::move(ball_box.front());
ball_box.erase(ball_box.begin());
*/
n_ball_box.push_back(std::move(b));
}
std::vector<ball_ptr> old_balls;
std::vector<ball_ptr> new_balls;
...
move(old_balls, new_balls);
Related Topics
Writings Functions (Procedures) for Data.Table Objects
Assign Headers Based on Existing Row in Dataframe in R
How to Ignore Case When Using Str_Detect
What Is a Neat Command Line Equivalent to Rstudio's Knit HTML
More Efficient Means of Creating a Corpus and Dtm with 4M Rows
Select Unique Values with 'Select' Function in 'Dplyr' Library
Change the Index Number of a Dataframe
Compare If Two Dataframe Objects in R Are Equal
Ggplot2: Overlay Density Plots R
Hiding Personal Functions in R
How to Create Textarea as Input in a Shiny Webapp in R
How to Get Around Error "Factor Has New Levels" in Cross-Validation Glm