简体   繁体   中英

How can I compare if a char is higher or lower in alphabetical order than another?

Pretty much as the title. I'm writing a linked list and I need a function to sort the list alphabetically, and I'm pretty stumped. Not sure how this has never come up before, but I have no idea how to do it other than to create my own function listing the entire alphabet and comparing positions of letters from scratch.

Is there any easy way to do this?

Edit for clarity:

I've got a linear linked list of class objects, each class object has a char name, and I'm writing a function to compare the name of each object in the list, to find the highest object alphabetically, and then find the next object down alphabetically, etc, linking them together as I go. I already have a function that does this for an int field, so I just need to rewrite it to compare inequalities between alphabetical characters where a is largest and z is smallest.

In hindsight that was probably a lot more relevant than I thought.

I think a couple of the answers I've gotten already should work so I'll pop back and select a best answer once I've gotten it working.

I'm also working with g++ and unity.

I think that in general case the best approach will be to use std::char_traits:

char a, b;
std::cin >> a >> b;
std::locale loc;
a = std::tolower(a, loc);
b = std::tolower(b, loc);

std::cout << std::char_traits::compare(&a, &b, 1u);

But in many common situations you can simply compare chars as you do it with other integer types.

 #include <stdio.h>
 #include <ctype.h>

 void main(void) {
  char a = 'X', b = 'M';
  printf("%i\n", a < b);
  printf("%i\n", b < a);

  printf("%i\n", 'a' < 'B'); 
  printf("%i\n", tolower('a') < tolower('B'));
 }

prints out:

 0
 1
 0
 1

char s are still numbers, and can be compared as such. The upper case letters and lower case letters are all in order, with the upper case letters before the lower. (Such that 'Z' < 'a'.) See an ASCII table .

My guess is that your list contains char* as data (it better contain std::string s as data). If the list is composed of the latter, you can simply sort using the overloaded std::string 's operator< , like

return str1 < str2; // true if `str1` is lexicographically before `str2` 

If your list is made of C-like null-terminated strings, then you can sort them using std::strcmp like

return std::strcmp(s1, s2); 

or use the std::char_traits::compare (as mentioned by @Anton) like

return std::char_traits<char>::compare(s1, s2, std::min(std::strlen(s1), std::strlen(s2)));

or sort them via temporary std::string s (most expensive), like

return std::string(s1) < std::string(s2); // here s1 and s2 are C-strings

If your list simply contains characters, then, as mentioned in the comments,

return c1 < c2; // returns true whenever c1 is before c2 in the alphabet

If you don't care about uppercase/lowercase, then you can use std::toupper to transform the character into uppercase, then always compare the uppercase.

As you can see from this ASCII table, all of the alphanumeric characters appear in the correct alphabetical order, regarding their actual values:

在此处输入图片说明

"Is there any easy way to do this?"

So yes, comparing the character values will provide to have them sorted in alphabetical order.

would something like below suffice ? convert everything to upper first.

class compareLessThanChar{
public:
    bool operator()(const char a, const char b)
    { return toupper(a) < toupper(b); }
}


std::multiset<char, compareLessThanChar> sortedContainer;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM