2011-10-18 14 views
5

Mam std::vector<Word> data że jest wyłączony z struct poniżej:Sortowanie wektor <Struct> alfabetycznie

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

ja przeczytałem w słowach z pliku i pchnął go do mojego wektorze przechowującej słowa w łańcuchu powyżej wzdłuż z numerem linii, na którym pojawia się słowo. Teraz muszę uporządkować alfabetycznie słowa i próbuję następujące:

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

Jednak gdy próbuję skompilować następujące dostaję szalone długą listę błędów. Wierzę, że jest to spowodowane algorytmem sortowania próbującym porównać wektor.begin() z vector.end(), ale nie wie, jak ocenić słowo struct do innego słowa struct.

Jednak ja też nie. Zastanawiam się, jak porównać ciąg zawarty z wzorami w wektorze.

Odpowiedz

19

W tym scenariuszu należy napisać funkcję, która porównuje dwie struktury Word i przekazuje tę funkcję do 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); 

W this question można znaleźć rozwiązanie, jeśli chcesz napisać rodzajowe komparator do porównywania obiektów na podstawie atrybutu.

Aktualizacja Ponieważ mieliśmy C++ 11 i C++ 14 przez pewien czas teraz, jestem dodanie roztworu za pomocą lambda, bo to jest chyba lepiej teraz praktyka:

std::sort(data.begin(), data.end(), [](const Word& lhs, const Word& rhs) { 
    return lhs.word < rhs.word; 
}); 
+0

Dokładnie tego potrzebowałem. Dziękuję Ci. –

5

należy wdrożyć operator< do listy struct Word

+3

Należy to zrobić tylko wtedy, gdy dokonane porównanie jest standardowym sposobem porównywania obiektów tego typu. Jeśli jest to specjalny przypadek, preferowana powinna być funkcja wolna lub funktor. –

+0

@ BjörnPollex: Zgadzam się, wydawało mi się, że tak jest w tym przypadku. – amit

2

Zamiast sortowania wektor potem, można również użyć pojemnika, który przechowuje swoje pozycje w uporządkowany sposób.

#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; 
0

Jeśli twój kompilator obsługuje wyrażenia LAMDA, możesz dodać go jako funkcję porównania.

std::sort(data.begin(), data.end(), 
[](const Word & lhs, const Word & rhs) 
{ 
    return lhs.word < rhs.word; 
}); 
Powiązane problemy