Search code examples
sortingc++11stdvectorerase

Erasing case in-sensitive duplicates from std::vector<std::string>


This is weird, can't erase remove case in-sensitive duplicates from std::vector? Can someone please let me know how to achieve this? Here is my code:

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

using namespace std;

int main()
{
    vector<string> stringVec = {"John", "Bob", "Joe", "Zack", "Randy", "bob", "joe", "andy"};
    sort(stringVec.begin(), stringVec.end());
    stringVec.erase(unique(stringVec.begin(), stringVec.end()),stringVec.end());

    for(unsigned i=0; i<stringVec.size(); i++)
    {
        cout<<stringVec[i]<<endl;
    }

    return 0;
}

Output for above code:

Success time: 0 memory: 3432 signal:0
Bob
Joe
John
Randy
Zack
andy
bob
joe

I expect at least joe, bob to be removed and andy to be placed in first index.


Solution

  • You can solve this by passing a case-insensitive predicate to both sort() and unique():

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <string>
    
    using namespace std;
    
    string lowercase(string x)
    {
      transform(x.begin(), x.end(), x.begin(), [](char x) { return tolower(x); });
      return x;
    }
    
    
    int main()
    {
        vector<string> stringVec = {"John", "Bob", "Joe", "Zack", "Randy", "bob", "joe", "andy"};
        sort(stringVec.begin(), stringVec.end(),
          [](const string &a, const string &b) { return lowercase(a) < lowercase(b); }
        );
        stringVec.erase(
          unique(stringVec.begin(), stringVec.end(),
            [](const string &a, const string &b) { return lowercase(a) == lowercase(b); }
          ),
          stringVec.end()
        );
    
        for(unsigned i=0; i<stringVec.size(); i++)
        {
            cout<<stringVec[i]<<endl;
        }
    
        return 0;
    }
    

    Live example