Thread: Another Vector question

  1. #1
    Registered User
    Join Date
    Sep 2006
    Location
    Kansas City
    Posts
    76

    Another Vector question

    This time I have a vector of names, some of them are duplicates. I am having troubles figuring out how to copy just the duplicates to a second vector and remove the them form the first vecotor. So far I got this:

    Code:
        for ( int i = 0 ; i < friends.size () ; i ++ )
              {
                for ( int j = i - 1 ; j < friends.size () ; j++ )
                  {
    
                   if ( friends[i] == friends [j] )     //  if duplicate is found
                        {
    
                             cout << friends[i] << endl;
                             enemies.push_back ( friends [i] )                      
              
                         } 
    
                  }
    
               }
    But this code coppiec all elements from vector friends to vector enemies. How can I fix this ?

  2. #2
    Registered User
    Join Date
    Mar 2005
    Posts
    16
    So in your inner loop, you need to check all the values in the vector except the current one -- the definition of a duplicate. I modified your code a bit:
    Code:
        for ( int i = 0 ; i < friends.size () ; i ++ )
              {
                for ( int j = 0; j < friends.size () ; j++ ) //loop through the whole thing
                  {
                   if (j == i) continue; //THE KEY LINE -- skips the check if we are looking at the same element
                   if ( friends[i] == friends [j] )     //  if duplicate is found
                        {
    
                             cout << friends[i] << endl;
                             enemies.push_back ( friends [i] )                      
              
                         } 
    
                  }
    
               }
    I haven't tested this, but it should work (famous last words).


    EDIT: if you also need to remove the duplicates from the original, look into the vector::erase function.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Location
    Kansas City
    Posts
    76
    Thanks for the help, this works. Yet I have another problem

    I have a vector in my public section of a class, it is a function (which transfers duplicates - see above).

    The function starts like this :

    Code:
    vector <string> People::get_duplicates()
     {
         .....
     }
    This compiles and works, but everytime the program gets to this function it freazes and I get that

    vectors.exe has encountered a problem and needs to close. We are sorry for the inconvenience.
    message. What is causing this problem ?

  4. #4
    Registered User zouyu1983's Avatar
    Join Date
    Nov 2006
    Location
    Fuzhou University, Fujian, China
    Posts
    35
    It seems like it causes by the pointer. Maybe in somewhere your pointer is out of the bound (sorry , I come frome china, so my English is not good)

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I am having troubles figuring out how to copy just the duplicates to a second
    >vector and remove the them form the first vecotor.
    Good news! That's a common problem. Better news! It's easily solvable with the standard library:
    Code:
    #include <algorithm> 
    #include <iostream>
    #include <iterator>
    #include <vector>
    
    template <typename T, int N>
    char (&array(T(&)[N]))[N];
    
    int main()
    {
      int a[] = {1,2,3,4,4,2,4,3,1,2,3,5,3,4,5,5,3,4,5};
      std::vector<int> v ( a, a + sizeof array ( a ) );
      std::vector<int>::iterator end;
      std::vector<int> save;
    
      // Original list
      copy ( v.begin(), v.end(), std::ostream_iterator<int> ( std::cout, " " ) );
      std::cout<<'\n';
    
      sort ( v.begin(), v.end() );
      end = unique ( v.begin(), v.end() );
      save.assign ( end, v.end() );
      v.erase ( end, v.end() );
    
      // Final list
      copy ( v.begin(), v.end(), std::ostream_iterator<int> ( std::cout, " " ) );
      std::cout<<'\n';
    
      // Saved duplicates
      copy ( save.begin(), save.end(), std::ostream_iterator<int> ( std::cout, " " ) );
      std::cout<<'\n';
    }
    My best code is written with the delete key.

  6. #6
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Quote Originally Posted by Prelude
    >I am having troubles figuring out how to copy just the duplicates to a second
    >vector and remove the them form the first vecotor.
    Good news! That's a common problem. Better news! It's easily solvable with the standard library:
    Gahh!!! I was going to suggest that exact solution. Of course, if it's important to the OP to keep the original order of elements in the source vector then the sort kinda ruins that.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >Of course, if it's important to the OP to keep the original order of elements in
    >the source vector then the sort kinda ruins that.
    I've been in that situation many times. Or so I thought at first. It turns out that in practice (most of the time, it seems), if you get to the point where you have duplicates stored and want to remove them, the current order isn't important.
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed