我使用C++中的sort()
函数对我自己定义的"Game"类型的对象向量进行排序。为此,我正在手动编写一个函数,该函数将代替operator<
,并将作为第三个参数传递给sort()
函数。首先,我根据分数进行比较。然后,如果比分持平,我会根据球队名称进行比较。
我需要的是一个函数alphabetical(string s1, string s2)
,如果s1
在字典中位于s2
之前,它将返回true。例如:
alphabetical("aardvark", "apple"); //true
alphabetical("balloon", "zebra"); //true
alphabetical("zebra", "apple"); //false
如果字符串相同,我还希望它返回false。图书馆里有什么我可以用的吗?或者,我该如何编写函数?我希望我给人的印象很清楚。
std::string
实现了一个字典式的小于比较运算符本身,这意味着stringA < stringB
通常应该做你想做的事情。如果创建std::list<std::string> words
,则按字母顺序排序将与words.sort();
一样简单
您的自定义Game
类可以将其小于比较运算符简单地实现为:
return (score < rhs.score) || (score == rhs.score && team < rhs.team)
值得注意的是,字典排序并不总是人类所期望的。Jeff Atwood在这篇文章中讨论了所谓的"自然排序顺序"与字典排序顺序。他的帖子还提供了一些资源,如果你需要这样的排序,你可以从中找到算法。
如果字符串都是上限或下限,则标准字符串比较将起作用。我相信它甚至适用于不再使用的字符编码,比如EBSIDIC或其他什么。
如果您将使用混合情况,则这不起作用,因为"A"大于"z"。要想做到这一点,你需要使用stricmp之类的东西。您也可以覆盖basic_string的char_traits来进行不敏感的比较。
如果你想写排序,这样它就把"A"放在"A"之前,反之亦然,但把"b"放在了"A"之后。。。那么你需要自己写。使用ASCII表应该相当简单,现在大多数操作系统都使用ASCII表。
如果你必须支持英语以外的语言,那么这个问题实际上就变得无关紧要了。
如果您使用的是std::string
s,您可以只使用<
。但是,如果您已经有了char*
,您不想(或不能)更改它,并且希望避免转换为std::string
的开销,那么您可以使用std::lexicographical_compare()
。
当然,在这两种情况下,您可能希望进行不区分大小写的比较。我不确定std::string
的正确解决方案是什么,可能与char_traits
有关,但对于lexicographical_compare()
,您可以提供一个比较器:
bool alphabetical(const char *str1, const char *str2) {
return std::lexicographical_compare(str1, &str1[strlen(str1)], str2, &str2[strlen(str2)], [](char a, char b){
return tolower(a) < tolower(b);
});
}