我如何比较一个字符按字母顺序排列的顺序是高于还是低于另一个?
How can I compare if a char is higher or lower in alphabetical order than another?
和标题差不多。我正在写一个链接列表,我需要一个函数来按字母顺序对列表进行排序,我很困惑。不确定以前从未出现过这种情况,但除了创建我自己的列出整个字母表并从头开始比较字母位置的函数之外,我不知道该怎么做。
有什么简单的方法可以做到这一点吗?
为清楚起见编辑:
我有一个 class object 的线性链表,每个 class object 都有一个字符名称,我正在编写一个函数来比较列表中每个 object 的名称,按字母顺序查找最高的 object,然后按字母顺序查找下一个 object,依此类推,边走边将它们链接在一起。我已经有一个为 int 字段执行此操作的函数,所以我只需要重写它来比较字母字符之间的不等式,其中 a 最大,z 最小。
事后看来,这可能比我想象的更重要。
我认为我已经得到的几个答案应该可以工作,所以我会返回并 select 一个最佳答案,一旦我得到它工作。
我也在使用 g++ 和 unity。
#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'));
}
打印出来:
0
1
0
1
char
仍然是数字,可以这样比较。大写字母和小写字母都是按顺序排列的,大写字母在小写字母之前。 (这样 'Z' < 'a'。)请参阅 ASCII table。
我的猜测是您的列表包含 char*
作为数据(最好包含 std::string
作为数据)。如果列表由后者组成,您可以简单地使用重载的 std::string
的 operator<
进行排序,例如
return str1 < str2; // true if `str1` is lexicographically before `str2`
如果你的列表是由类似 C 的以 null 结尾的字符串组成的,那么你可以使用 std::strcmp
对它们进行排序,比如
return std::strcmp(s1, s2);
或使用 std::char_traits::compare
(如@Anton 所述),例如
return std::char_traits<char>::compare(s1, s2, std::min(std::strlen(s1), std::strlen(s2)));
或通过临时 std::string
s(最昂贵)对它们进行排序,例如
return std::string(s1) < std::string(s2); // here s1 and s2 are C-strings
如果您的列表仅包含字符,那么,如评论中所述,
return c1 < c2; // returns true whenever c1 is before c2 in the alphabet
如果不关心uppercase/lowercase,那么可以用std::toupper
把字符转成大写,然后一直比较大写。
从这个 ASCII table 可以看出,所有字母数字字符都以正确的字母顺序出现,关于它们的实际值:
"Is there any easy way to do this?"
所以是的,比较字符值将提供让它们按字母顺序排序。
我认为一般情况下最好的方法是使用 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);
但在许多常见情况下,您可以简单地将字符与其他整数类型进行比较。
像下面这样的东西就足够了吗?首先将所有内容转换为上层。
class compareLessThanChar{
public:
bool operator()(const char a, const char b)
{ return toupper(a) < toupper(b); }
}
std::multiset<char, compareLessThanChar> sortedContainer;
和标题差不多。我正在写一个链接列表,我需要一个函数来按字母顺序对列表进行排序,我很困惑。不确定以前从未出现过这种情况,但除了创建我自己的列出整个字母表并从头开始比较字母位置的函数之外,我不知道该怎么做。
有什么简单的方法可以做到这一点吗?
为清楚起见编辑:
我有一个 class object 的线性链表,每个 class object 都有一个字符名称,我正在编写一个函数来比较列表中每个 object 的名称,按字母顺序查找最高的 object,然后按字母顺序查找下一个 object,依此类推,边走边将它们链接在一起。我已经有一个为 int 字段执行此操作的函数,所以我只需要重写它来比较字母字符之间的不等式,其中 a 最大,z 最小。
事后看来,这可能比我想象的更重要。
我认为我已经得到的几个答案应该可以工作,所以我会返回并 select 一个最佳答案,一旦我得到它工作。
我也在使用 g++ 和 unity。
#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'));
}
打印出来:
0
1
0
1
char
仍然是数字,可以这样比较。大写字母和小写字母都是按顺序排列的,大写字母在小写字母之前。 (这样 'Z' < 'a'。)请参阅 ASCII table。
我的猜测是您的列表包含 char*
作为数据(最好包含 std::string
作为数据)。如果列表由后者组成,您可以简单地使用重载的 std::string
的 operator<
进行排序,例如
return str1 < str2; // true if `str1` is lexicographically before `str2`
如果你的列表是由类似 C 的以 null 结尾的字符串组成的,那么你可以使用 std::strcmp
对它们进行排序,比如
return std::strcmp(s1, s2);
或使用 std::char_traits::compare
(如@Anton 所述),例如
return std::char_traits<char>::compare(s1, s2, std::min(std::strlen(s1), std::strlen(s2)));
或通过临时 std::string
s(最昂贵)对它们进行排序,例如
return std::string(s1) < std::string(s2); // here s1 and s2 are C-strings
如果您的列表仅包含字符,那么,如评论中所述,
return c1 < c2; // returns true whenever c1 is before c2 in the alphabet
如果不关心uppercase/lowercase,那么可以用std::toupper
把字符转成大写,然后一直比较大写。
从这个 ASCII table 可以看出,所有字母数字字符都以正确的字母顺序出现,关于它们的实际值:
"Is there any easy way to do this?"
所以是的,比较字符值将提供让它们按字母顺序排序。
我认为一般情况下最好的方法是使用 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);
但在许多常见情况下,您可以简单地将字符与其他整数类型进行比较。
像下面这样的东西就足够了吗?首先将所有内容转换为上层。
class compareLessThanChar{
public:
bool operator()(const char a, const char b)
{ return toupper(a) < toupper(b); }
}
std::multiset<char, compareLessThanChar> sortedContainer;