5

I have a std::vector<Word> data that is off of the struct below:

struct Word
{
    std::string word;
    int line_number;
};

I have read in words from a file and pushed it in to my vector storing the words in the string above along with the line number that the word appears on. Now I need to sort the words alphabetically and I attempt the following:

    std::sort(data.begin(), data.end());

However when I try to compile the following I get a crazy long list of errors. I believe this is due to the sort algorithm trying to compare the vector.begin() to vector.end() but it doesn't know how to evaluate the struct word to another struct word.

However neither do I. I am stumped on how to compare the string contained with the structs in the vector.

4 Answers4

20

In this scenario you should write a function that compares two Word structs and pass that function to std::sort.

bool compare_by_word(const Word& lhs, const Word& rhs) {
    return lhs.word < rhs.word;
}

std::sort(data.begin(), data.end(), compare_by_word);

In this question you can find solution if you want to write a generic comparator for comparing objects based on an attribute.

Update Since we've had C++11 and C++14 for a while now, I'm adding a solution using a lambda, because that is probably the better practice now:

std::sort(data.begin(), data.end(), [](const Word& lhs, const Word& rhs) {
    return lhs.word < rhs.word;
});
Community
  • 1
  • 1
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
5

you should implement operator< to your struct Word

amit
  • 175,853
  • 27
  • 231
  • 333
  • 3
    This should only be done if the comparison you do is the standard way to compare objects of this type. If it is a special case, a free function or functor should be preferred. – Björn Pollex Oct 18 '11 at 07:16
  • @BjörnPollex: I agree, it seemed to me it is the case in here. – amit Oct 18 '11 at 07:27
1

Instead of sorting the vector afterward, you can also use a container which stores its items in a sorted manner.

#include <string>
#include <set>
#include <map>

struct Word
{
    std::string word;
    int line_number;
};

struct compare_by_word
{
    bool operator()(const Word& lhs, const Word& rhs)
    {
        return lhs.word < rhs.word;
    }
};

std::set<Word, compare_by_word> foo;

std::map<std::string, int> bar;
Rudi
  • 19,366
  • 3
  • 55
  • 77
0

If your compiler supports lamda expressions you could just add one as the compare function.

std::sort(data.begin(), data.end(),
[](const Word & lhs, const Word & rhs)
{
    return lhs.word < rhs.word;
});
Cpt. Red
  • 102
  • 3