3

I have a vector of vector (loops) which contains integer values. Some inside vectors are duplicating but their element order is not the same. Now, I want to get a vector of vector without having any duplicate inner vectors. here is an example for my vec of vec;

loops = ((9 18 26 11 9), (9 11 26 18 9),(9 18 25 16 9),(11 45 26 11),( 11 26 45 11),( 16 49 25 16),( 16 25 49 16),(18 9 11 26 18),( 18 9 16 25 18),( 25 16 49 25),( 26 11 45 26))

To identify whether any inner vector is a duplicate of another inner vector; I have developed a function IsDuplicate. This tells me, (9 18 26 11 9) and (9 11 26 18 9) are duplicates then I can delete the second or all other duplicates.

To remove duplicate vectors inside my vector of vector, I have implemented following codes.

Vector<vector<int> > loops;
Vector<vector<int> > ::iterator no1, no2;
Int setno1, setno2;

for (no1=loops.begin(), setno1=0; no1!=loops.end(); no1++, setno1++){
       set1 = *no1;
       for (no2=loops.begin()+setno1, setno2=setno1; no2!=loops.end(); setno2++){
            set2 = *no2;
            if (set2.IsDuplicate(set1))  loops.erase(loops.begin()+setno2);
            else no2++;
       }

  }

it took very very long time and i thought my program is crasihing. so, Please help me to rectify this issue.

also, i tried with this. this works but i got a wrong answer. any help please.

01   int first=0; bool duplicates=false;  
02   do {     
03        set1 = loops[first];     
04        for (no2=loops.begin()+1, setno2=1;  no2!=loops.end();  setno2++){     
05             set2 = *no2;      
06             if (set2.IsPartOf(set1)){      
07                 loops.erase(loops.begin()+setno2);     
08                 duplicates = true;      
09             }      
10             else no2++;     
11        }      
12        first++;      
13       } while(!duplicates); 
niro
  • 947
  • 3
  • 13
  • 30

1 Answers1

6

The idiomatic way is to use the Erase/Remove idiom with a custom predicate. To check for duplicate vectors and without modifying the contents of your vectors, write a predicate that takes its arguments by value, sort the vectors and use std::equal.

bool equal_vector(std::vector<int> a, std::vector<int> b) {
  std::sort(a.begin(), a.end());
  std::sort(b.begin(), b.end());

  return std::equal(a.begin(), a.end(), b.begin());
}

// use it like this
v.erase( remove_if(v.begin(), v.end(), equal_vector), v.end() );

As to why your current code fails: Erasing an element from a vector invalidates all other iterators to that vector that are currently in existence thus vector::erase returns a valid iterator to the position after the element that has been removed.

The stdlib also provides the set and multiset container which look like a much better fit for your purpose.

pmr
  • 58,701
  • 10
  • 113
  • 156
  • thanks for the response. but me, i am using DevC++ and i can not use idiomatic way (I tried to use that way earlier to remove elements inside a vector, but could do. so i hope, dev cannot recognise these idioms.), if you can, please add the traditional way to do the same thing. then, i can learn and implement. Also, i can not use set as my real objct class is not integer (it is my own class PointNumber) but inherited from integers and posted as interger for the simplicity. - thanks in advance- – niro Oct 02 '11 at 13:08
  • 1
    @g_niro I have no experience with DevC++, but this seems impossible. Do you include the right headers? You need at least `algorithm` and `vector` for the above to work. If the `algorithm` header doesn't support `remove` or `sort` you should switch to a viable platform ASAP. – pmr Oct 02 '11 at 13:12
  • @g_niro Also the `int` and `PointNumber` difference does in no way affect that code as long as `PointNumber` has `operator<` defined. – pmr Oct 02 '11 at 13:13
  • @g_niro So, I don't get what is keeping this solution from working for you. You might want to show us the code and the errors in a separate question. – pmr Oct 02 '11 at 13:25
  • sorry, i could say you, i cant change my element order as i need this orderd values later. (i guess, no way to use sort). – niro Oct 03 '11 at 10:45
  • @pmr I think that `equal_vector` should be UnaryPredicate, as stated in doc of [remove_if](https://en.cppreference.com/w/cpp/algorithm/remove). How did you manage to make it to compare the elements? – samu Sep 04 '19 at 09:25