2011-10-18 39 views
5

Tôi đã một std::vector<Word> data đó là tắt của các cấu trúc dưới đây:Sắp xếp một vector <Struct> theo thứ tự abc

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

Tôi đã đọc trong lời nói từ một tập tin và đẩy nó vào vector của tôi lưu trữ các từ trong chuỗi trên cùng với số dòng mà từ đó xuất hiện. Bây giờ tôi cần phải sắp xếp các từ theo thứ tự bảng chữ cái và tôi cố gắng như sau:

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

Tuy nhiên khi tôi cố gắng biên dịch sau, tôi nhận được danh sách lỗi dài. Tôi tin rằng điều này là do thuật toán sắp xếp cố gắng so sánh vector.begin() với vector.end() nhưng nó không biết cách đánh giá từ struct đến từ struct khác.

Tuy nhiên, không làm I. Tôi bị bối rối về cách so sánh chuỗi chứa với các cấu trúc trong vectơ.

Trả lời

19

Trong trường hợp này, bạn nên viết hàm so sánh hai cấu trúc Word và chuyển hàm đó thành 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); 

Trong this question bạn có thể tìm giải pháp nếu bạn muốn viết so sánh chung để so sánh các đối tượng dựa trên thuộc tính.

Cập nhật Kể từ khi chúng tôi đã có C++ 11 và C++ 14 trong một thời gian bây giờ, tôi thêm một giải pháp sử dụng một lambda, bởi vì đó có lẽ là thực hành tốt hơn bây giờ:

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

Đó chính xác là những gì tôi cần. Cảm ơn bạn. –

5

bạn nên triển khai operator< vào struct Word

+3

Việc này chỉ nên thực hiện nếu so sánh bạn thực hiện là cách tiêu chuẩn để so sánh các đối tượng thuộc loại này. Nếu nó là một trường hợp đặc biệt, một chức năng miễn phí hoặc functor nên được ưa thích. –

+0

@ BjörnPollex: Tôi đồng ý, có vẻ như với tôi ở đây. – amit

2

Thay vì sắp xếp vectơ sau đó, bạn cũng có thể sử dụng vùng chứa lưu trữ các mục của nó theo cách được sắp xếp.

#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

Nếu trình biên dịch của bạn hỗ trợ biểu thức lamda bạn chỉ có thể thêm một làm hàm so sánh.

std::sort(data.begin(), data.end(), 
[](const Word & lhs, const Word & rhs) 
{ 
    return lhs.word < rhs.word; 
}); 
Các vấn đề liên quan