-
adding to vector of vector<int>, check if element already present
I have a vector<vector<int> > that I am adding data to,
Code:
vector<vector<int> > new_set_of_paths;
// to each path1[i], add a neighbor of last_vertex
for(j=0; j<last_vertex_delta; j++) {
current_neighbor = vertex_list[last_vertex_in_path].neighbor_numbers[j];
new_set_of_paths[path_count].push_back( current_neighbor );
path_count ++;
}
I need to do two things.:
1. check if "current_neighbor" is already a member of new_set_of_paths[path_count][i,j,k]
2. if it is already a member, delete new_set_of_paths[path_count] from the vector<vector<int>>, slide up the remaining elements, re-size, etc.
I'm sure I could do this by looping, checking, copying, etc, but I'm sure an algorithm would be better. I sure I could locate using find or find_if, but when I have done this before, I was deleting the element, but in this case, I need to delete the entire vector. This is complicated because the vector is stored in another vector.
I have tried,
Code:
vector<vector<int> > new_set_of_paths;
vector<int>::iterator path_iterator;
// to each path1[i], add a neighbor of last_vertex
for(j=0; j<last_vertex_delta; j++) {
current_neighbor = vertex_list[last_vertex_in_path].neighbor_numbers[j];
// search path to see if new vertex is already present
path_iterator = find(new_set_of_paths[path_count].begin(),
new_set_of_paths[path_count].end(),
current_neighbor);
cout << "current_neighbor " << current_neighbor << endl;
cout << "path_iterator " << path_iterator << endl;
new_set_of_paths[path_count].push_back( current_neighbor );
path_count ++;
}
but this doesn't compile. I am getting
Code:
In function `std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > add_vertex_to_path(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, const int&)':
src/src_client_main/internal_hbond_get_path.cpp:287: error: no match for 'operator<<' in 'std::operator<< [with _Traits = std::char_traits<char>](((std::basic_ostream<char, std::char_traits<char> >&)(&std::cout)), ((const char*)"path_iterator ")) << path_iterator'
Any suggestions?
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
The problem, in plain English, is that the output stream has no idea how to output a path_iterator.
Code:
cout << "path_iterator " << path_iterator << endl;
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
Paul McKenzie
The problem, in plain English, is that the output stream has no idea how to output a path_iterator.
Code:
cout << "path_iterator " << path_iterator << endl;
Regards,
Paul McKenzie
Yes, I forgot to make the output a pointer.
This sort of gets me going,
Code:
vector<vector<int> > new_set_of_paths;
vector<int>::iterator path_iterator;
vector<int> check_path;
for(j=0; j<last_vertex_delta; j++) {
current_neighbor = vertex_list[last_vertex_in_path].neighbor_numbers[j];
if(path_length > 2) {
check_path = new_set_of_paths[path_count];
// search path to see if new atom is already part of path
path_iterator = find(check_path.begin(),
check_path.end(),
current_neighbor);
cout << "last_atom_in_path " << last_atom_in_path << endl;
cout << "current_neighbor " << current_neighbor << endl;
cout << "path_iterator " << * path_iterator << endl;
cout << endl;
}
if(path_iterator == 0) {
new_set_of_paths[path_count].push_back( current_neighbor );
path_count ++; //
}
check_path.clear();
}
I don't seem to know how to evaluate if the iterator indicates that it found a match. I can't do, if(path_iterator == 0), or if(*path_iterator == 0), and I also tried if(path_iterator > check_path.end()) and a few similar things. I can't seem to find a reference that shows how to evaluate an iterator. The * iterator value prints as 0 when a match isn't found, but I can't seem to get the syntax for working that into the conditional.
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
What is "path_count"? Where does it come from? Also, why do you need to keep a count? Why are you not iterating over a range instead of trying to "hand_count" using path_count?
In other words:
Code:
for_each(new_set_of_paths.begin(),
new_set_of_paths.end(), whatever);
The "whatever" can be ironed out later, but is this what your major loop (which you didn't show us) consist of?
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
LMHmedchem
I don't seem to know how to evaluate if the iterator indicates that it found a match.
Use std::find_if(), not std::find().
Then you check the return iterator is equal to check_path.end(). If it is, then the item was not found.
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
Paul McKenzie
Use std::find_if(), not std::find().
Then you check the return iterator is equal to check_path.end(). If it is, then the item was not found.
Regards,
Paul McKenzie
Find_if returns an iterator to an element if that element returns as true from some second function, right? That second function would have to test equality against the elements in the vector being checked, but I'm not sure what that would look like.
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
Paul McKenzie
What is "path_count"? Where does it come from? Also, why do you need to keep a count? Why are you not iterating over a range instead of trying to "hand_count" using path_count?
In other words:
Code:
for_each(new_set_of_paths.begin(),
new_set_of_paths.end(), whatever);
The "whatever" can be ironed out later, but is this what your major loop (which you didn't show us) consist of?
Regards,
Paul McKenzie
I am looping on all the neighbors of a vertex as a means of building a path (in the graph sense). The number of branches at a vertex is equal the the number of neighbors-1, since you don't want to go backwards. I need to loop on the number of neighbors, but I am always creating one less path then the number of neighbors. This means I can't use the loop iterator to assign where in new_set_of_paths[] the new path will be added. This code is repeated for each branch point, so the total number of paths of a given length (starting from a given vertex) is something that needs to accumulate if the data is to be assigned in the way I set it up. Keeping an independent count is the first thing that came to mind for doing this.
I am sure there are other ways to do this, and I'm sure you will notice a conspicuous lack of algorithms, iterators, objects, and functors in my code. I never seem to get much past containers and do loops. I only have a bit more to get this working, more or less, and then I will post a longer version of the algorithm for comment.
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
LMHmedchem
Find_if returns an iterator to an element if that element returns as true from some second function, right? That second function would have to test equality against the elements in the vector being checked, but I'm not sure what that would look like.
LMHmedchem
Looking at your code again, you can use std::find. The issue is this:
Quote:
I don't seem to know how to evaluate if the iterator indicates that it found a match. I can't do, if(path_iterator == 0), or if(*path_iterator == 0), and I also tried if(path_iterator > check_path.end())
You compare the iterator to end(). You do not compare to 0, or compare of the iterator is > end().
Code:
SomeIterator = std::find(container.begin(), container.end(), whatever);
if ( SomeIterator != container.end() )
{
// the item exists, and it is *SomeIterator
}
else
{
// the item doesn't exist
}
Iterators are not guaranteed to be integral values, so you can't compare them to 0 or use operator > to compare "greater". Even if the iterator is an integral type, there is no guarantee that the last item in the sequence is "greater than" another item. For example, std::deque() is more or less a data structure broken up in chunks, but acts like an array, so you can't compare using "greater than".
That leaves us with one thing -- comparing if the iterator is equal or not equal some other iterator and that is what the code in red does.
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
Thanks, I'm making some progress. I am working under the assumption that I can use the individual row of my vector<vector<int>> as I would any container,
Code:
path_iterator = find(new_set_of_paths[path_count].begin(),
new_set_of_paths[path_count].end(),
current_neighbor);
meaning that I don't have to copy out the data into a regular vector<int>.
It is working more or less, but I need to remove rows of the <vector<int>> that I'm not going to add to. Right now, it is crashing because the rows are still there. This code searches the current row of new_set_of_paths[] to see if a vertex is already present in the path. If the vertex is not already there, it is added, if not it is skipped.
Code:
vector<vector<int> > new_set_of_paths;
if(new_set_of_paths.size() != 0) {
// iterator for vector search
vector<int>::iterator path_iterator;
// to each path1[i], add a neighbor of last_atom
for(j=0; j<last_vertex_delta; j++) {
// lookup value of next neighbor to possibly add
current_neighbor = vertex_list[last_vertex_in_path]neighbor_numbers[j];
// check to make sure that any added vertex is not already in the path
// prevents moving backwards and through ring closures
path_iterator = find(new_set_of_paths[path_count].begin(),
new_set_of_paths[path_count].end(),
current_neighbor);
// new verticies are added to path_temp[path_count] because not all
// verticies are added and the total is cumulative over all branches
if(path_iterator != new_set_of_paths[path_count].end()) {
cout << "don't add " << current_neighbor << endl;
} else {
cout << "do add " << current_neighbor << endl;
new_set_of_paths[path_count].push_back( current_neighbor );
path_count ++; //
}
}
}
I need to add code to the don't add part of the conditional that would remove new_set_of_paths[path_count] row from the new_set_of_paths vector. It's more complex than that, because I actually don't want removal in every case, but I do need to figure out the syntax for removal when I do need it.
I have tried,
Code:
int erase_at = path_count-1;
new_set_of_paths.erase(new_set_of_paths.begin()+erase_at);
but I'm not sure that's right. I need to work a bit on when to do this and when not to because I'm sure it will go boom if I don't pay attention to that. I know erase can foul up iterator values, but I'm not sure it that is an issue here or not.
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
LMHmedchem
It is working more or less, but I need to remove rows of the <vector<int>> that I'm not going to add to. Right now, it is crashing because the rows are still there.
OK. One question:
Can you determine by scanning the vector what needs to be removed without removing anything? In other words, instead of trying to go through each element, checking, and then removing (using erase), can you go through the entire vector, know which elements you want to remove, and "mark" them as elements you want to remove without actually erasing them?
If so, then use
1) std::remove_if() / vector::erase() combination if all you want to do is erase the items from the vector
OR
2) std::stable_partition() / vector::erase() if you want to do something to the removed items before erasing them.
By scanning the vector and rearranging the vector so that the items to remove are at the end of the vector, instead of trying to go one-by-one erasing them makes the code much more stable. But you need to determine if scanning the entire vector first is possible with what you want to do.
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
What I need to remove is an entire vector from a vector<vector<int>>. I guess this could be thought of as a single element of the vector<vector<int>>.
for example, where
new_set_of_paths.size() = 2
new_set_of_paths[0][17, 19, 21]
new_set_of_paths[1][17, 19, 20]
current_neighbor = 21;
I am checking current_neighbor against the values in new_set_of_paths[0] and new_set_of_paths[1]. If 21 is found in either vector, than that vector needs to be removed,
new_set_of_paths.size() = 1
new_set_of_paths[0][17, 19, 20]
new_set_of_paths[1] needs to be deleted and new_set_of_paths needs to be renumbered, etc.
I think this is the last thing I need to do to get the code working in the general sense. I will post it once I get that far. If you would like to see more at this point, let me know.
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
LMHmedchem
What I need to remove is an entire vector from a vector<vector<int>>. I guess this could be thought of as a single element of the vector<vector<int>>.
Given your description, I wrote this test program:
Code:
#include <vector>
#include <algorithm>
typedef std::vector<int> IntVect;
typedef std::vector<IntVect> IntVect2D;
struct PathRemover
{
PathRemover(int val) : m_val(val) {}
bool operator()(const IntVect& v) const
{
// if m_val is in this vector, mark it to be removed
return std::find(v.begin(), v.end(), m_val) != v.end();
}
int m_val;
};
int main()
{
// Test data
int data1[] = {17, 19, 21};
int data2[] = {17, 19, 20};
// Here is our 2d vector
IntVect2D new_set_of_paths(2);
// Set our test data
new_set_of_paths[0] = IntVect(data1, data1 + 3);
new_set_of_paths[1] = IntVect(data2, data2 + 3);
// remove the item with 21 in it.
new_set_of_paths.erase(std::remove_if(new_set_of_paths.begin(), new_set_of_paths.end(), PathRemover(21)), new_set_of_paths.end());
}
At the end, you will see that the path with 21 is removed.
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
I am having some issues compiling. I am getting the following error,
Code:
In function `std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > add_atoms_to_path(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, const int&)':
src/src_client_main/internal_hbond_get_path.cpp:255: error: expected `,' or `...' before '&' token
src/src_client_main/internal_hbond_get_path.cpp:256: error: ISO C++ forbids declaration of `IntVect' with no type
src/src_client_main/internal_hbond_get_path.cpp: In member function `bool add_atoms_to_path(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, const int&)::PathRemover::operator()(int) const':
src/src_client_main/internal_hbond_get_path.cpp:258: error: `v' undeclared (first use this function)
src/src_client_main/internal_hbond_get_path.cpp:258: error: (Each undeclared identifier is reported only once for each function it appears in.)
src/src_client_main/internal_hbond_get_path.cpp: In function `std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > add_atoms_to_path(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, const int&)':
src/src_client_main/internal_hbond_get_path.cpp:347: error: no matching function for call to `remove_if(__gnu_cxx::__normal_iterator<std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >, __gnu_cxx::__normal_iterator<std::vector<int, std::allocator<int> >*, std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > >, add_atoms_to_path(std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >&, const int&)::PathRemover)'
With my line numbering,
Code:
struct PathRemover // 252
{ // 253
PathRemover(int val) : m_val(val) {} // 254
bool operator()(const IntVect& v) const // 255
{ // 256
// if m_val is in this vector, mark it to be removed // 257
return std::find(v.begin(), v.end(), m_val) != v.end(); // 258
} // 259
// 260
int m_val; // 261
}; // 262
new_set_of_paths.erase(std::remove_if(new_set_of_paths.begin(), // 345
new_set_of_paths.end(), // 346
PathRemover(current_neighbor)), // 347
new_set_of_paths.end()); // 348
It seems the issue is primarily with the v. vector in the struct.
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
LMHmedchem
I am having some issues compiling. I am getting the following error,
The code I posted compiles successfully in Comeau C++ and Visual Studio 2010.
Where are these lines?
Code:
typedef std::vector<int> IntVect;
typedef std::vector<IntVect> IntVect2D;
I used typedefs, because it's easier to deal with rather than those long definitions.
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
Paul McKenzie
The code I posted compiles successfully in Comeau C++ and Visual Studio 2010.
Where are these lines?
Code:
typedef std::vector<int> IntVect;
typedef std::vector<IntVect> IntVect2D;
I used typedefs, because it's easier to deal with rather than those long definitions.
Regards,
Paul McKenzie
You're right, it does compile. I was trying to put the struct in a .h file, but I don't think I had all the includes and the typedefs in the right place.
This seems to be working and giving me the output I want, so I will post a more complete version of what I'm trying to get done.
LMHmedchem
-
2 Attachment(s)
Re: adding to vector of vector<int>, check if element already present
Well it seems I explained this incorrectly. The above erase code you posted looks like it searches through the entire vec<vec> for any sub vector with the number 21 in it, which is what I said I needed.
Code:
new_set_of_paths.erase(std::remove_if(new_set_of_paths.begin(),
new_set_of_paths.end(),
PathRemover(21)),
new_set_of_paths.end());
The fact is that a repeat number will be in more than one place and in some cases, the vector shouldn't be deleted.
I am working on this graph,
Attachment 29110
I am creating and storing paths of length 1-5, starting at vertex 1 (or any specified vertex). The number of path1 paths emanating from a given vertex is equal to the number of neighbors, which is 2 in this case (simple delta = 2). A path1 is one edge connecting two vertices, for anyone reading this who has never worked with graph theory.
There are two path1 paths from vertex 1
1,2
1,3
To build path2 paths, I use each of the path1s as a base. Looking at the last element in the first path1, vertex 2 has a delta of 3, so three paths can branch from v2.
The three neighbors of v2 are 1,4,5.
To build path2, I create delta copies of path1 1,2
1,2
1,2
1,2
and add one neighbor of 2 (last element in the path1 base) to each copy,
1,2,1
1,2,4
1,2,5
then I loop to the second path1 path
1,3
vertex 3 also has three neighbors (1,11,12), so I add three copies of 1,3
1,2,1
1,2,4
1,2,5
1,3
1,3
1,3
and then one neighbor of 3 to each copy,
1,2,1
1,2,4
1,2,5
1,3,1
1,3,11
1,3,12
these path2 paths will form the base path for path3 subgraphs, etc
The problem is that you don't want repeat elements in a path. Repeats mean that the path is moving backwards, or through a circuit, and neither is a path by definition or interest. This means that,
1,2,1
1,3,1
need to be deleted, or never created in the first place.
My thought was that, before adding the neighbor, I would scan the vector to see if it was already there, if not, add it, if it is, delete the vector. It may be simpler to wait until all of the paths of a given length have been enumerated and then loop through the vec<vec> checking the last element against the earlier ones.
I setup a very crude double loop to do this, and the algorithm does work now.
Code:
vector<int> temp_copy;
bool copy;
for(i=0; i<new_set_of_paths.size(); i++) {
copy = true;
temp_copy = new_set_of_paths[i];
last_vertex_in_path = temp_copy.back();
for(j=0; j<temp_copy.size()-1; j++) {
if(last_vertex_in_path == temp_copy[j]) { copy = false; }
}
if(copy == true) { copy_vector.push_back(temp_copy); }
temp_copy.clear();
}
new_set_of_paths = copy_vector;
I get the expected,
path2[0] 1,2,4
path2[1] 1,2,5
path2[2] 1,3,11
path2[3] 1,3,12
I have tired up to path5 for a number of start vertices and it seems to work fine.
I tried modifying the erase code you posted to check the last element against the others, but I guess I'm not clear enough on how it works. Repeat elements can occur anywhere in the vector, so the entire vector must be scanned. For example,
1,3,12,11,3
I have attached the src code for this. It's a bit long, but everything interesting is in the first 222 lines. Everything after that is just loading the graph and the starting vertex.
So far, the algorithm works, is fast, and I don't see much of anywhere it could blow up, but I would really like to learn how to better make use of algorithms and not do so much for() double looping everywhere.
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
In your new code, you have a small issue here:
Code:
last_vertex_in_path = temp_copy.back();
for(j=0; j<temp_copy.size()-1; j++) {
if(last_vertex_in_path == temp_copy[j]) { copy = false; }
}
You don't check to see if temp_copy is empty. Your loop will go haywire since you subtract 1 from 0.
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
Try this:
Code:
#include <vector>
#include <algorithm>
typedef std::vector<int> IntVect;
typedef std::vector<IntVect> IntVect2D;
bool CopyVect(const IntVect& vect)
{
if ( vect.empty() )
return true;
int last_vertex_in_path = vect.back();
IntVect::const_iterator last = vect.end();
--last;
IntVect::const_iterator it = std::find(vect.begin(), last, last_vertex_in_path);
if ( it != last)
return false;
return true;
}
int main()
{
// Test data
int data1[] = {17, 19, 21};
int data2[] = {17, 19, 20};
// Here is our 2d vector
IntVect2D new_set_of_paths(2);
// Set our test data
new_set_of_paths[0] = IntVect(data1, data1 + 3);
new_set_of_paths[1] = IntVect(data2, data2 + 3);
new_set_of_paths.erase(
std::remove_if(new_set_of_paths.begin(), new_set_of_paths.end(), CopyVect), new_set_of_paths.end());
}
The CopyVect function should do the same thing you're doing now.
1) It gets the last item in the vector.
2) It searches for the last element in the vector, up until the item before the last one.
3) Returns true of false, depending on whether the item is found or not.
Then in the main() program, the new_set_of_paths is trimmed of the removed vectors.
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
I think that possibly the return values should be the opposite,
Code:
bool CopyVect(const IntVect& vect)
{
if ( vect.empty() )
return true;
int last_vertex_in_path = vect.back();
IntVect::const_iterator last = vect.end();
--last;
IntVect::const_iterator it = std::find(vect.begin(), last, last_vertex_in_path);
if ( it != last)
// return false;
// return true;
return true;
return false;
}
so that the function returns true if a match is found. It seems to work properly if I switch those bool values. Then I get the following output,
path1[0] 1,2
path1[1] 1,3
path2[0] 1,2,4
path2[1] 1,2,5
path2[2] 1,3,11
path2[3] 1,3,12
path3[0] 1,2,4,6
path3[1] 1,2,5,6
path3[2] 1,2,5,7
path3[3] 1,3,11,12
path3[4] 1,3,11,13
path3[5] 1,3,12,11
path4[0] 1,2,4,6,5
path4[1] 1,2,5,6,4
path4[2] 1,2,5,7,8
path4[3] 1,2,5,7,9
path4[4] 1,2,5,7,10
path4[5] 1,3,11,13,14
path4[6] 1,3,11,13,15
path4[7] 1,3,11,13,16
path4[8] 1,3,12,11,13
path5[0] 1,2,4,6,5,7
path5[1] 1,2,5,7,10,21
path5[2] 1,2,5,7,10,22
path5[3] 1,3,11,13,16,17
path5[4] 1,3,11,13,16,18
path5[5] 1,3,12,11,13,14
path5[6] 1,3,12,11,13,15
path5[7] 1,3,12,11,13,16
Quote:
Originally Posted by
Paul McKenzie
In your new code, you have a small issue here:
Code:
last_vertex_in_path = temp_copy.back();
for(j=0; j<temp_copy.size()-1; j++) {
if(last_vertex_in_path == temp_copy[j]) { copy = false; }
}
You don't check to see if temp_copy is empty. Your loop will go haywire since you subtract 1 from 0.
I don't think it is possible for temp_copy to be empty, but this code is being replaced by the erase code you posted. This is exactly why I would like to get away from endless looping and make more use of algorithms, which are less susceptible to going out of bounds and such.
Do you think there is anything else in the algorithm that is poorly formed? I understand that may be a "you asked for it" kind of question.
LMHmedchem
-
Re: adding to vector of vector<int>, check if element already present
Quote:
Originally Posted by
LMHmedchem
I think that possibly the return values should be the opposite,
Code:
bool CopyVect(const IntVect& vect)
{
if ( vect.empty() )
return true;
int last_vertex_in_path = vect.back();
IntVect::const_iterator last = vect.end();
--last;
IntVect::const_iterator it = std::find(vect.begin(), last, last_vertex_in_path);
if ( it != last)
// return false;
// return true;
return true;
return false;
}
so that the function returns true if a match is found. It seems to work properly if I switch those bool values. Then I get the following output
OK. As long as the function does the correct thing, then this should work.
Quote:
I don't think it is possible for temp_copy to be empty,
You should always check for bad data, and subtracting 1 from the end() iterator and then blowing up on an empty container is one runtime error that happens a lot, but can be avoided. So I highly suggest that you check for an empty container somewhere, whether it is in this function or before.
Quote:
Do you think there is anything else in the algorithm that is poorly formed? I understand that may be a "you asked for it" kind of question.
The thing is, I didn't really study your code that hard except to see what loops could be replaced with algorithms. This is a test case of me not knowing everything that you want to accomplish, and by just looking at your loops, writing the equivalent using the STL algorithms.
BTW, this is the final code:
Code:
bool CopyVect(const IntVect& vect)
{
return vect.empty() // return true if container is empty
|| // OR
// return true if last element cannot be found in the range [0 ... n-1)
(std::find(vect.begin(), vect.end()-1, vect.back()) != vect.end()-1);
}
//...
new_set_of_paths.erase(
std::remove_if(new_set_of_paths.begin(), new_set_of_paths.end(), CopyVect), new_set_of_paths.end());
Regards,
Paul McKenzie
-
Re: adding to vector of vector<int>, check if element already present
Could you perhaps store the paths in a std::map with the path id("1,2,4" or 124) as a key? That way you could never have more than one instance of a path.
-
Re: adding to vector of vector<int>, check if element already present