2012-02-24 130 views
2

我试图创建一个函数来按名称或姓氏对地址簿中的联系人列表进行排序。按C++语言按字母顺序排列对象列表

void sortList (list<Contact> & address_book){ 

//define two iterators - first to point to the first element from the list, second to the second element 
list<Contact>::iterator it = address_book.begin(); 
list<Contact>::iterator it2 = address_book.begin(); 
it2++; 

//get the last name for the first 2 contacts 
string last_name1 = it->get_last_name(); 
string last_name2 = it2->get_last_name(); 

int i = 0; 

while (i < last_name1.length() && i < last_name2.length()){ 

     if (last_name1[i] < last_name2[i]){ 
      swap(it, it2); 
      break; 
     } 

} 
} 

我确定我没有正确地做,但是我对这些迭代器有点失落。我也知道我应该有另一个while循环来遍历我的所有联系人,直到所有的联系人被排序,但是,老实说,我不知道如何实现它。

回答

6

的std ::列表有一个过载的成员函数排序,即

按升序对元素进行排序。保证等同元素的顺序得以保留。第一个版本使用运算符<来比较元素,第二个版本使用给定的比较函数comp。

为了让你可以使用函子比较函数:

struct sort_by_name { 
    bool operator()(const Contact &a, const Contact &b) 
    { return a.get_name() < b.get_name(); } 
}; 
struct sort_by_last_name { 
    bool operator()(const Contact &a, const Contact &b) 
    { return a.get_last_name() < b.get_last_name(); } 
}; 

或简单免费功能

bool cmp_by_name(const Contact &a, const Contact &b) 
{ return a.get_name() < b.get_name(); } 
bool cmp_by_last_name(const Contact &a, const Contact &b) 
{ return a.get_last_name() < b.get_last_name(); } 

,并调用它要么

address_book.sort(sort_by_name()); 
address_book.sort(sort_by_last_name()); 

address_book.sort(cmp_by_name); 
address_book.sort(cmp_by_last_name); 

存取器GET_NAME()和get_last_name()必须是const。

+1

这些更简单的功能就像一个魅力。没有错误,所以永远。谢谢! – Adrian 2012-02-24 00:48:48

4

不要做自己的排序。使用std::sort()。你需要来提供定制的比较 - 是这样的:

struct LastNameComp { 
    bool operator()(const Contact& a, const Contact& b) const { 
     return a.get_last_name() < b.get_last_name(); 
    } 
} 
⋮ 
std::sort(address_book.begin(), address_book.end(), LastNameComp()); 

如果你有机会到C++编译器11,你可以做的更好:

std::sort(address_book.begin(), address_book.end(), 
    [](const Contact& a, const Contact& b) { 
     return a.get_last_name() < b.get_last_name(); 
    }); 
+0

我得到这个错误24''传递const的联系 '为'本的std ::参数字符串联系方式:: get_last_name()' 丢弃qualifiers' – Adrian 2012-02-24 00:25:46

+1

@Adrian:你'get_last_name()'函数或许应该被声明为const,除非你有一个真正的,真正的*真正的理由不会:'std :: string get_last_name()const {// ....' – greyfade 2012-02-24 00:33:21

+0

跟着注释,但仍然错误'没有匹配函数调用'sort(std :: _ List_iterator ,std :: _ List_iterator ,main(int,char **):: LastNameComp)'' – Adrian 2012-02-24 00:39:19

1

扩大给出的答案使用std::lexicographical_compare并列出内部排序。

struct LastNameComp { 
     bool operator()(const Contact& a, const Contact& b) { 
      return std::lexicographical_compare(
       a.get_last_name().begin(), a.get_last_name().end(), 
       b.get_last_name().begin(), b.get_last_name().end(), 
      ); 
     } 
    }; 

    address_book.sort(LastNameComp()); 
+0

+1,这对非英国人姓名来说尤其是个好主意。 – greyfade 2012-02-24 00:35:12

+0

原谅我的nievity,但这比运营商<字符串更好吗?我不认为lexcompare处理utf8或其他... – 2012-02-24 16:14:29