这是我目前的代码:
#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 C
。
答案 0 :(得分: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,那么String Algorithms库中就有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));
}
答案 1 :(得分:4)
使用默认<
的默认比较器(char_traits< char >
)会将您的列表排序为C a b
。
请参阅list::sort。
为了达到所需的顺序a b C
,您可以:
char_traits
,或 string
类型列表
为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);
答案 2 :(得分: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;
}
答案 3 :(得分:0)
答案 4 :(得分:0)
自C++11起,您也可以使用lambda expression代替定义比较器函数/结构:
#include <list>
#include <string>
#include <cstring>
#include <iostream>
using namespace std;
int main()
{
list<string> list_;
list_.emplace_back("C");
list_.emplace_back("a");
list_.emplace_back("b");
list_.sort([](const string& a, const string& b) {
return (strcasecmp(a.c_str(), b.c_str()) < 0);
});
for (auto const &str : list_)
cout << str << endl;
return 0;
}
输出:
a
b
C
注意:函数strcasecmp()
(在@ RobertS.Barnes的答案中也建议使用)不是C ++标准的,因此并非在每个系统上都可用。例如,如果您使用的是Visual Studio,则可以改用_stricmp()
。
如果国际化对您来说是一个问题,那么您可以像@Manuel在回答中那样使用语言环境。