CecchinoSMI
CecchinoSMI

Reputation: 169

Consideration on vectors

I have two vector: locs_current_all and sc_current_peaks_pos (both filled with position values), some elements are in common. In vector sc_current_peaks_pos there are the indexes that I want to erase from vector sc_current_peaks_pos.

So here my code.

1st method: try to copy in the vector non_short_circuit_current only the different elements between
locs_current_all and sc_current_peaks_pos.

vector<int> non_short_circuits_current;
int j_nsc=0;
for(int i=0;i<=sc_current_peaks_pos.size()-1;i++){

    for(int k=j_nsc;k<=locs_current_all.size()-1;k++){
        j_nsc++;
        if(sc_current_peaks_pos[i]==locs_current_all[k])
            non_short_circuits_current.push_back(locs_current_all[k]);

           //else break ;

    }

}

2nd method: erase from vector locs_current_all the elements inside sc_current_peaks_pos.

vector<int> non_short_circuits_current;
std::for_each(std::begin(sc_current_peaks_pos), std::end(sc_current_peaks_pos), [&](int indexOpp){
 non_short_circuits_current.erase(locs_current_all [indexOpp]);
 });// erase wants more parameters!!!

All the two methods fail. Thanks in advance for your help.

Upvotes: 0

Views: 92

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 311156

If I have understood your task correctly then try something similar

#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdlib>
#include <ctime>


int main() 
{
    const int N = 20;
    std::srand( ( unsigned )std::time( 0 ) );

    std::vector<int> v1( N );
    std::vector<int> v2( N );

    std::generate( v1.begin(), v1.end(), [] { return std::rand() % N; } );
    std::generate( v2.begin(), v2.end(), [] { return std::rand() % N; } );

    for ( int x : v1 ) std::cout << x << ' ';
    std::cout << std::endl;

    for ( int x : v2 ) std::cout << x << ' ';
    std::cout << std::endl;

    auto is_present = [&]( int x )
    { 
        return std::find( v2.begin(), v2.end(), x ) != v2.end();
    };

    v1.erase( std::remove_if( v1.begin(), v1.end(), is_present ), v1.end() );

    for ( int x : v1 ) std::cout << x << ' ';
    std::cout << std::endl;

    for ( int x : v2 ) std::cout << x << ' ';
    std::cout << std::endl;

    return 0;
}

The output is

15 4 9 9 11 13 14 16 19 5 6 14 11 2 5 0 6 0 9 12 
16 18 5 14 10 1 5 1 19 18 10 15 2 19 4 5 4 10 13 16 
9 9 11 6 11 0 6 0 9 12 
16 18 5 14 10 1 5 1 19 18 10 15 2 19 4 5 4 10 13 16 

EDIT: If the vectors are ordered then you could use std::binary_search instead if std::find as it is used in my sample.

Upvotes: 1

Niall
Niall

Reputation: 30624

I was busy answering this and my internet connection died, so I'm not going to post any more code samples, the previous answer has some nice code for you to work with; but I thought it might be worthwhile noting that:

  • std::remove() does not physically delete or erase elements from the container It only moves elements within the container.
  • vector.erase() deletes elements from a container, since the container itself will have enough knowledge to remove elements from itself (i.e. because this varies between containers, the methods need to be members).
  • Once elements in a vector are erased (or inserted), it could potentially invalidate any copies of an iterators you may have made, so it is generally a good idea to assume all of the are invalid and re-get them (unless you are absolutely sure that they will be still valid). Basically if you are looping from the vec.begin() to vec.end() and you erase an element before the end of the loop, you are already in trouble.
  • The "erase remove" pattern is fairly common when erasing elements in the vector, of course you'll need to define your custom criteria is for the deletion is to be.
  • If they are sorted sequences, the std library may already have some algorithms you may want to use.

Upvotes: 0

Related Questions