10

Just want to remove duplicates. Pool is vector<pair<string, int>> but I seem to miss some elements at the start of the vector somehow. Can anyone verify the logic of the removal? Thanks :)

Pool Master::eliminateDuplicates(Pool generation)
{
    for(int i = 0; i < generation.size(); i++)
    {
        string current = generation.at(i).first;

        for(int j = i; j < generation.size(); j++)
        {
            if(j == i)
            {
                continue;
            }
            else
            {
                string temp = generation.at(j).first;
                if(current.compare(temp) == 0)
                {
                    Pool::iterator iter = generation.begin() + j;
                    generation.erase(iter);
                }
            }
        }
    }

    return generation;
}
Jarrod Cabalzar
  • 408
  • 1
  • 5
  • 24

2 Answers2

24

If you don't mind sorting the vector, then you can use std::unique. That would be O(Nlog(N))

#include <iostream>
#include <algorithm>
#include <vector>

int main() 
{
    std::vector<int> v{1,2,3,1,2,3,3,4,5,4,5,6,7};
    std::sort(v.begin(), v.end()); 
    auto last = std::unique(v.begin(), v.end());
    v.erase(last, v.end());
    for (const auto& i : v)
      std::cout << i << " ";
    std::cout << "\n";
}
juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • 7
    +1 Someone should write a wiki / FAQ entry for all the bread and butter vector usages. – TemplateRex May 10 '13 at 06:32
  • 2
    @rhalbersma, SO should maintain a list of the most commonly asked questions on popular topics, like Top 10 C++ Questions or something. That would be handy. :D – Jarrod Cabalzar May 10 '13 at 12:48
  • I wonder why in all the answers about using `std::unique` nobody seems worth to mention that `unique` does not consider the last element. – tomi.lee.jones Dec 21 '13 at 14:21
  • @tomi.lee.jones I don't really understand what you mean here. `std::unique`'s behaviour seems quite intuitive to me. – juanchopanza Dec 21 '13 at 14:25
  • @juan from the documentation, "removes all consecutive duplicate elements from the range [first, last)", so (1,2,3,1) will be (1,2,3,1). How is that intuitive? I know why the range is right-open and why it must be, but unless you are sure there is no dupe on the last position, unique seems useless. – tomi.lee.jones Dec 21 '13 at 15:10
  • 2
    @tomi.lee.jones Because all standard library algorithms work on open ranges, and usually we pass begin, end, which is open in that way. – juanchopanza Dec 21 '13 at 15:45
  • 1
    If you are going to sort, why not `std::sort`? –  May 18 '14 at 14:57
4

This is a very common issue.

Because after you erase an element the position j pointed will skip one element due to the j++ on the for loop. the easiest solution to solve the problem based on your code is to add j-- after generation.erase(iter):

  generation.erase(iter);
  j--;
diwatu
  • 5,641
  • 5
  • 38
  • 61