Hello I have a problem with vectors I have double loop where I erase elements from both vectors and I have a problem when I remove element from first loop's vector it is showing the error "vector too long". I had similar problem in my last project but this time I can't to solve it the same way I did last time. The error is showing after last bullet hit the wall.
collision func
void Game::BulletHit(int j, std::vector <Bullet>& team, std::vector <Squares>& square,
std::vector <Squares>& square2)
{
for (size_t i = 0; i < bulletTeam1.size(); i++)
{
if(team[i].bullet.getGlobalBounds().intersects(square[j].square.getGlobalBounds()))
{
int x = square[j].square.getPosition().x;
int y = square[j].square.getPosition().y;
//sf::Color color = square[j].square.getFillColor();
square.erase(square.begin() + j);
Squares1.square.setFillColor(sf::Color::White);
Squares1.square.setPosition(sf::Vector2f(x, y));
square2.push_back(Squares1);
team.erase(team.begin() + i);
std::cout << "collison " << team.size() << std::endl;
}
}
}
code where i use it
for (size_t i = 0; i < team1.size(); i++)
{
BulletHit(i, bulletTeam2, team1, team2);
//BulletHit(i, bulletTeam3, team1, team3);
//BulletHit(i, bulletTeam4, team1, team4);
}
I don't think we have enough information to fully understand your problem.
One thing that I can point out and you maybe didn't catch is, that calling square.erase(square.begin() + j); will remove the j-th element from the square vector. But then you continue to run the inner loop, thus in the next iteration, you'll again remove the j-th element. This will run until there are fewer than j elements in the vector and then crash or the inner loop exits early. Either way, I believe this may not be the intended goal here and you may want to remove the j-th element outside the inner loop, so that the j-th element is only removed once.
Related
Let's say I have a vector of integers:
vector<int> v(n);
Which I fill up in a for loop with valid values. What I want to do is to find a index of a given value in this vector. For example if I have a vector of 1, 2, 3, 4 and a value of 2, i'd get a index = 1. The algorithm would assume that the vector is sorted in ascending order, it would check a middle number and then depending of it's value (if its bigger or smaller than the one we're asking for) it would check one of halves of the vector. I was asked to do this recursive and using pointer. So I wrote a void function like:
void findGiven(vector<int> &v){
int i = 0;
int *wsk = &v[i];
}
and I can easily access 0th element of the vector. However I seem to have some basic knowledge lacks, because I can't really put this in a for loop to print all the values. I wanted to do something like this:
for (int j = 0; j<v.size(); j++){
cout << *wsk[j];
}
Is there a way of doing such a thing? Also I know it's recurisve, I'm just trying to figure out how to use pointers properly and how to prepare the algorithm so that later I can build it recursively. Thanks in advance!
The correct way is:
for (int wsk : v) {
cout << wsk;
}
If you insist on pointers:
int* first = v.data();
for (size_t j = 0; j < v.size(); ++j) {
cout << first[j];
}
I was searching how to insert values in a 2D vector and I found a really simple answer.
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
int value;
std::cout << "Value for 2D array at pos(" << i + 1 << ", " << j + 1 << "): ";
std::cin >> value;
arr[i].push_back(value); //<- the answer I found
}
}
I am a little confused because how can I insert a number in (i,j), if I am only giving the i?
Is j acting under the hood even though I didn't declare it when I push back the value?
You are adding values to an array of arrays.
(arr[i]) is actually an array itself. Every i represents a row, and every j represents a column. The first for loop is iterating through the rows and the second for loop is iterating through the columns (I'm sure you knew that though). arr[i].push_back(value) is actually adding value to arr[i][j] if you want to think of it that way. The first push_back adds value to arr[i][0], the second adds value to arr[i][1] and so on. If you had a 2D array of 0's for example, you would use arr[i][j]. The only reason you don't use it in this case is because if you reference arr[i][j] you will get an out of bounds exception since the index j doesn't exist yet (push_back creates it). I hope that makes sense. I thought an explanation made more sense than code since you already have the correct code and just needed an explanation.
You do not need to know the j value. Here is why, the out-most for loop iterating from 0 until the end of row. Therefore, the "i" is an index that coordinating from 0 to the end of row.
As each end of row has been reached, the inner for loop j index will move to next column.
In brief, you need only row index to fill the element in each row of 2d array, where the column is iterated to move over next column when i >= row.size.
I am learning c++ and I am currently at halt.
I am trying to write a function such that:
It takes in input a one dimensional vector and an integer which specifies a row.
The numbers on that row are put into an output vector for later use.
The only issue is that this online course states that I must use another function that I have made before that allows a 1d vector with one index be able to have two indexes.
it is:
int twod_to_oned(int row, int col, int rowlen){
return row*rowlen+col;
}
logically what I am trying to do:
I use this function to store the input vector into a temporary vector as a 2D matric with i as the x axis and y as the y axis.
from there I have a loop which reads out the numbers on the row needed and stores it in the output vector.
so far I have:
void get_row(int r, const std::vector<int>& in, std::vector<int>& out){
int rowlength = std::sqrt(in.size());
std::vector <int> temp;
for(int i = 0; i < rowlength; i++){ // i is vertical and j is horizontal
for(int j = 0; j < rowlength; j++){
temp[in[twod_to_oned(i,j,side)]]; // now stored as a 2D array(matrix?)
}
}
for(int i=r; i=r; i++){
for(int j=0; j< rowlength; j++){
out[temp[i][j]];
}
}
I'm pretty sure there is something wrong in the first and last loop which turns into a 2D matric then stores the row.
I starred the parts that are incomplete due to my lack of knowledge.
How could I overcome this issue? I would appreciate any help, Many thanks.
takes in input a one dimensional vector
but
int rowlength = std::sqrt(in.size());
The line of code appears to assume that the input is actually a square two dimensional matrix ( i.e. same number of rows and columns ) So which is it? What if the number of elements in the in vector is not a perfect square?
This confusion about the input is likely to cuase your problem and should be sorted out before doing anything else.
I think what you wanted to do is the following:
void get_row(int r, const std::vector<int>& in, std::vector<int>& out) {
int rowlength = std::sqrt(in.size());
std::vector<std::vector<int>> temp; // now a 2D vector (vector of vectors)
for(int i = 0; i < rowlength; i++) {
temp.emplace_back(); // for each row, we need to emplace it
for(int j = 0; j < rowlength; j++) {
// we need to copy every value to the i-th row
temp[i].push_back(in[twod_to_oned(i, j, rowlength)]);
}
}
for(int j = 0; j < rowlength; j++) {
// we copy the r-th row to out
out.push_back(temp[r][j]);
}
}
Your solution used std::vector<int> instead of std::vector<std::vector<int>>. The former does not support accessing elements by [][] syntax.
You were also assigning to that vector out of its bounds. That lead to undefined behaviour. Always use push_back or emplate_back to add elements. Use operator [] only to access the present data.
Lastly, the same holds true for inserting the row to out vector. Only you can know if the out vector holds enough elements. My solution assumes that out is empty, thus we need to push_back the entire row to it.
In addition: you might want to use std::vector::insert instead of manual for() loop. Consider replacing the third loop with:
out.insert(out.end(), temp[r].begin(), temp[r].end());
which may prove being more efficient and readable. The inner for() look of the first loop could also be replaced in such a way (or even better - one could emplace the vector using iterators obtained from the in vector). I highly advise you to try to implement that.
I'm trying to simulate the mean behaviour of an ensemble of neurons. This means I need to do calculations with a matrix of a couple of billions of elements (steps~106, neurons~104).
To avoid eating my whole RAM (and dying trying) I decided to delete rows from the matrix as soon as I'm done doing calculations with it. I don't have too much experience with C++, but my understanding is that v.erase( v.begin()-i+1); should allow me to do so.
// Membrane potential matrix using st::vector
vector<vector<double>> v;
v.resize(steps + 1, vector<double>(neurons));
// Initialise v
for (size_t n = 0; n < neurons; n++) {
v[0][n] = v0;
}
double v_avg[steps + 1] = {v0};
// Loop
for (size_t i = 1; i < steps + 1; i++) {
for (size_t n = 0; n < neurons; n++) {
if(v[i-1][n] >= vp) {
v[i][n] = -vp;
}
else {
v[i][n] = v[i-1][n] + h * ( pow(v[i-1][n], 2) + I[i] + eta[n] );
}
v_avg[i] += v[i][n]; // Sum of membrane potentials
}
cout << "step " << i << "/" << steps << " done\n";
v.erase( v.begin()-i+1); // Erase row v[i-1]
v_avg[i] = v_avg[i]/neurons; // Mean membrane potential
}
v.erase( v.begin()+steps+1 ); // Erase last row
I'm not sure why I'm getting segmentation fault after the steps/2 step (I'm doing tests with a small steps value):
...
step 10/20 done
[1] 1791 segmentation fault (core dumped) ./qif_solve_vect
Update:
Thanks to #1201ProgramAlarm I see what's my problem. My question would be:
How can I work with the matrix in a way it isn't allocated from the very beginning.
How can I deallocate/free rows whilst keeping the indices (unlike v.erase( v.begin())). This is essential, as I will later implement different refractory times for each neuron when they produce a spike (v[i][n] = -vp;).
In your erase statement, you're subtracting from v.begin(), which will result in an invalid iterator since it will point before the start of the vector. You probably meant v.erase( v.begin() + i - 1);.
However, erasing like this isn't saving you any space since you already have the full matrix allocated. The erase will move all the remaining elements down one element, and your indexing for the next loop will be wrong (since you'd want to use v[0] all the time).
I wrote this c++ function to sort an array, it works, but it doesn't seem to work with the fist value: it isalways the bigger instead of the smaller!
void s_iSort (double a[])
{
cout << "INCREASING SORTER:\n\n";
unsigned int mx,maxx;
double temp;
cout << "Insert maximum element to sort: "; cin>>mx;
for (int c=0; c<mx; c++)
{
maxx=0;
for (int i=c; i<mx; i++)
if (a[i]<a[maxx])
maxx=i;
temp=a[c];
a[c]=a[maxx];
a[maxx]=temp;
}
cout << "\nDONE!\n\n";
}
What's worng with this?
You should either use a debugger, or try to explain your algorithm to a rubber duck. However, I am in a rubber duck mood and will point you to a mistake:
for (int c=0; c<mx; c++) {
maxx=0;
for (int i=c; i<mx; i++) if (a[i]<a[maxx]) maxx=i;
temp=a[c];
a[c]=a[maxx];
a[maxx]=temp;
}
In each iteration of this loop you want to go trough a range of elements, find the minimum value in that range and put it as the first element of that range. It works for the first iteration, but already on the second it goes wrong. You initialize maxx (which is supposed to be the first element in that range) to 0, ie the first element of the array. However you should only consider elements that have not yet been sorted, ie change it to
maxx = c;
Also note, that (apart from exercises) you should not write your own sorting algorithm but use std::sort.