c++ how to determine whether one word is before another in the alphabet

泪湿孤枕 提交于 2019-12-22 23:34:00

问题


I'm using the sort() function in C++ to sort a vector of objects of type 'Game', which I defined myself. To do this, I am manually writing a function that will act in place of the operator<, and which will be passed as the third parameter to the sort() function. First, I compare based on scores. Then, if scores are tied, I compare based on team name.

What I need is a function alphabetical(string s1, string s2), that will return true if s1 would come before s2 in the dictionary. For example:

alphabetical("aardvark", "apple"); //true
alphabetical("balloon", "zebra"); //true
alphabetical("zebra", "apple"); //false

I also want it to return false if the strings are identical. Is there something in a library that I could use? Or, how would I write the function? I hope I'm coming across clearly.


回答1:


std::string implements a lexicographical less-than comparison operator itself, meaning that stringA < stringB should usually do what you want. If you create a std::list<std::string> words, sorting alphabetically will be as simple as words.sort();

Your custom Game class could have its less-than comparison operator implemented simply as:

return (score < rhs.score) || (score == rhs.score && team < rhs.team)

It is worth noting that lexicographical sorting will not always be what a human would expect. Jeff Atwood goes into a discussion of so-called "natural sort order" versus lexicographical sort order in this post. His post also provides resources from which you will be able to find algorithms if such sorting is necessary to you.




回答2:


A standard string comparison will work if your strings are all upper or lower. I believe it even works with character encodings that are not used anymore, such as EBSIDIC or whatever.

If you'll have mixed case then this does not work because 'A' is greater than 'z'. For this to work you'll want to use things like stricmp or whatever. You can also override char_traits for your basic_string to do insensitive comparison.

If you want to write the sort such that it places 'A' before 'a' or visa-versa but 'b' after 'a'...then you'll need to write your own. It should be fairly simple using the ASCII table, which most operating systems today use.

If you have to support languages other than English the problem actually becomes non-trivial.




回答3:


If you're using std::strings you can just use <. But if you already have char*, you don't want to (or can't) change that, and you want to avoid the overhead of converting to std::string, then you can use std::lexicographical_compare().

Of course, in both cases, you probably want a case-insensitive comparison. Offhand I'm not sure what the right solution is for std::string, probably something to do with char_traits, but for lexicographical_compare() you can provide a comparator:

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);
    });
}


来源:https://stackoverflow.com/questions/12361447/c-how-to-determine-whether-one-word-is-before-another-in-the-alphabet

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!