2010-02-27 33 views
3
#include <list> 
#include <string> 
using std::string; 
using std::list; 

int main() 
{ 
    list <string> list_; 
    list_.push_back("C"); 
    list_.push_back("a"); 
    list_.push_back("b"); 

    list_.sort(); 
} 

sort()函数根据字符代码对元素进行排序?排序完成后,我希望结果为a b Csort std :: list区分大小写的元素

+0

如果您只需要单个ch字符,我强烈建议使用'char'而不是'std :: string'来减少一些膨胀。比较也会容易得多! – LiraNuna 2010-02-27 08:53:22

回答

4

使用默认char_traits<char>的默认比较器(<)会将您的列表排序为C a b

参见list::sort

为了达到预期的顺序a b C您可以:

  1. 撰写string类型列表与custom char_traits
  2. 提供自定义字符串比较的实例来sort,例如

    bool istring_less(const string& lhs, const string& rhs) { 
        string::const_iterator \ 
        lb = lhs.begin(), le = lhs.end(), 
        rb = rhs.begin(), re = rhs.end(); 
        const char lc, rc; 
        for (; lb != le && rb != re; ++lb, ++rb) { 
        lc = tolower(*lb); 
        rc = tolower(*rb); 
        if (*lc < *rc) return true; 
        if (*lc > *rc) return false; 
        } 
        // if rhs is longer than lhs then lhs<rhs 
        return (rb != re); 
    } 
    ... 
    list.sort(istring_less); 
    
+1

关于使用自定义特征:http://www.gotw.ca/gotw/029.htm – 2010-02-27 10:21:19

8

不区分大小写的字符比较是棘手。这就是为什么它是一个好主意,做他们在一个区域,合理的方式:

struct char_iless 
: public std::binary_function<char, char, bool> 
{ 
    std::locale loc; 

    char_iless(std::locale const & loc=std::locale()) : loc(loc) 
    { 
    } 

    bool operator()(char a, char b) const 
    { 
     return std::tolower(a, loc) < std::tolower(b, loc); 
    } 
}; 

这是你如何使用这个类来比较两个字符:

char_iless('a', 'b', my_locale); 

只需使用std::locale()作为my_locale如果你想使用默认设置的那个。

如果你可以使用Boost,那么在字符串算法库中有is_iless函子,它可以做同样的事情。

从字符比较字符串扩展,这是容易由于std::lexicographical_compare

struct str_iless 
: public std::binary_function<std::string, std::string, bool> 
{ 
    std::locale loc; 

    str_iless(std::locale const & loc=std::locale()) : loc(loc) 
    { 
    } 

    bool operator()(std::string const & a, std::string const & b) const 
    { 
     return std::lexicographical_compare(
      a.begin(), a.end(), 
      b.begin(), b.end(), 
      char_iless(loc) 
     ); 
    } 
}; 

现在,你拥有所有,它的要求来解决问题:

int main() 
{ 
    std::list<std::string> list; 
    list.push_back("C"); 
    list.push_back("a"); 
    list.push_back("b"); 

    // Sort using default locale 
    list.sort(str_iless()); 

    // Sort using French locale 
    // (warning: this locale format string is MS specific) 
    std::locale loc("French_France.1252"); 
    list.sort(str_iless(loc)); 
} 
+0

+1,比接受的答案中的手工编码版本更清洁的比较运算符。 – 2010-02-27 10:22:14

1

下面是什么,我认为是一些更清洁和一个明显更快的替代方案:

#include <string> 
#include <cstring> 
#include <iostream> 
#include <boost/algorithm/string.hpp> 

using std::string; 
using std::list; 
using std::cout; 
using std::endl; 

using namespace boost::algorithm; 

// recommended in Meyers, Effective STL when internationalization and embedded 
// NULLs aren't an issue. Much faster than the STL or Boost lex versions. 
struct ciLessLibC : public std::binary_function<string, string, bool> { 
    bool operator()(const string &lhs, const string &rhs) const { 
     return strcasecmp(lhs.c_str(), rhs.c_str()) < 0 ? 1 : 0; 
    } 
}; 

// If you need sorting according to the default system local 
struct ciLessBoost : std::binary_function<std::string, std::string, bool> 
{ 
    bool operator() (const std::string & s1, const std::string & s2) const { 
     return lexicographical_compare(s1, s2, is_iless()); 
    } 
}; 

int main(void) { 
    list <string> list_; 
    list_.push_back("C"); 
    list_.push_back("a"); 
    list_.push_back("b"); 

    list_.sort(ciLessLibC()); 
    list_.sort(ciLessBoost()); 

    return 0; 
} 
相关问题