0

I have this following code where I want to sort vector of string according to the last character of the string. I've done the following but the sorting is done by default rules.

Here's the overloading < part:

bool operator<(const string &s1, const string &s2){
    return s1.at(s1.size() - 1) < s2.at(s2.size() - 1);
}

This is in main:

vector <string> nameList;
int n;
cin>>n;
while(n--){
    string name;
    char str[100];
    cin>>str;
    name += str;
    nameList.push_back(name);
}

sort(nameList.begin(), nameList.end());
for(int i = 0; i < nameList.size(); i++)
    cout<<nameList.at(i)<<endl;

Code in ideone: LINK

  • 2
    Are you sure it is being called? Your `operator<` that is? – Niall Sep 22 '14 at 11:40
  • 4
    The string class [already have a full set of comparison operators](http://en.cppreference.com/w/cpp/string/basic_string/operator_cmp). Instead you might want to use the [`std::sort`](http://en.cppreference.com/w/cpp/algorithm/sort) function where you provide your own predicate (and name it something more appropriate instead). – Some programmer dude Sep 22 '14 at 11:41
  • @JoachimPileborg Thanks! It's working now by using a function with std::sort [New Code IDEONE](http://ideone.com/OzCeV1). – Sudarshan B Sep 22 '14 at 11:49
  • 1
    @Niall But why isn't it working this way. why not called?? – Sudarshan B Sep 22 '14 at 11:50
  • @sud6 because inside `std::sort` the first overload that gets found is the existing one in namespace `std`, so your overload is never found and never used – Jonathan Wakely Sep 22 '14 at 11:52
  • @sud6, It is not in the `std` namespace. And `std` already has an overload for the string `operator<`. – Niall Sep 22 '14 at 11:53

2 Answers2

6

As noted, your operator< is not being called, std::string already has overloaded operators in the std namespace.

There are two versions of std::sort, one that will use operator< and another that takes a custom predicate to sort the container. Add a custom predicate, you can still used sort to sort your vector as required;

#include <algorithm>
#include <string>
#include <iostream>
#include <vector>
using namespace std;

bool lastchar(const string &s1, const string &s2){
    return s1.at(s1.size() - 1) < s2.at(s2.size() - 1);
}

int main(){
        vector <string> nameList;
        int n;
        cin>>n;
        while(n--){
            string name;
            char str[100];
            cin>>str;
            name += str;
            nameList.push_back(name);
        }

        sort(nameList.begin(), nameList.end(), &lastchar);
        for(int i = 0; i < nameList.size(); i++)
            cout<<endl<<nameList.at(i);

        return 0;
}

I've called it lastchar, but you can name it what ever is best. As an added bonus, if you can used C++11 or above, you can make the predicate a lambda.

sort(nameList.begin(), nameList.end(), [] (const string &s1, const string &s2){
  return s1.at(s1.size() - 1) < s2.at(s2.size() - 1);
});
Niall
  • 30,036
  • 10
  • 99
  • 142
3

It's not being used, you have to pass it into std::sort - something like:

sort(nameList.begin(), nameList.end(), [](const string &s1, const string &s2) {
    return s1.at(s1.size() - 1) < s2.at(s2.size() - 1);
}
Paul Evans
  • 27,315
  • 3
  • 37
  • 54