当前位置:   article > 正文

C语言字母排序不分大小写,如何按字母顺序排序字符串数组(区分大小写,非标准排序规则)...

怎么判断一个字符串是否按照字母排序

保持一致的话一起…

对于单词列表,将“相同”的单词组合在一起(即使情况不同)往往更为有用.例如:

Keeping things together: Simple "M after m":

------------------------ -------------------

mars mars

mars bar mars bar

Mars bar milk

milk milk-duds

Milk milky-way

milk-duds Mars bar

milky-way Milk

Milky-way Milky-way

如果你想要排列第一列的单词,我会提出三种方式:

>使用strcasecmp()结合strcmp().

>使用isalpha(),tolower()和isupper()跟踪字符类型的单次执行实现.

>使用整理表的单次执行.

最后我讨论了两个选择:

>使用整理表建立任意排序.

>设置区域设置以使用基于区域设置的整理.

使用可用的库函数

如果可以这样做,请避免重新发明车轮.在这种情况下,我们可以通过使用POSIX函数strcasecmp()来查看它们是否与不区分大小写的比较相等,并在它们之后退回到strcmp().

int alphaBetize (const char *a, const char *b) {

int r = strcasecmp(a, b);

if (r) return r;

/* if equal ignoring case, use opposite of strcmp() result to get

* lower before upper */

return -strcmp(a, b); /* aka: return strcmp(b, a); */

}

(在某些系统上,不区分大小写的比较函数称为stricmp()或_stricmp(),如果您不可用,则在下面提供一个实现)

#ifdef I_DONT_HAVE_STRCASECMP

int strcasecmp (const char *a, const char *b) {

while (*a && *b) {

if (tolower(*a) != tolower(*b)) {

break;

}

++a;

++b;

}

return tolower(*a) - tolower(*b);

}

#endif

避免两次通过字符串

有时,现有的功能表现不够好,你必须做别的事情才能使事情更快.以下功能在单次传递中以大致相同的方式进行比较,而不使用strcasecmp()或strcmp().但是,它将所有非字母字符视为小于字母.

int alphaBetize (const char *a, const char *b) {

int weight = 0;

do {

if (*a != *b) {

if (!(isalpha(*a) && isalpha(*b))) {

if (isalpha(*a) || isalpha(*b)) {

return isalpha(*a) - isalpha(*b);

}

return *a - *b;

}

if (tolower(*a) != tolower(*b)) {

return tolower(*a) - tolower(*b);

}

/* treat as equal, but mark the weight if not set */

if (weight == 0) {

weight = isupper(*a) - isupper(*b);

}

}

++a;

++b;

} while (*a && *b);

/* if the words compared equal, use the weight as tie breaker */

if (*a == *b) {

return weight;

}

return !*b - !*a;

}

使用这种比较进行排序将保持牛奶和牛奶相邻,即使列表包括牛奶.

使用整理表

这是一种从“配置”动态创建整理表的方法.它用于说明一种对比技术来改变字符串的比较.

您可以映射字母表中的字母与一种简单的表格,描述您想要的字母(或NUL字节之外的任何字符)的相对顺序:

const char * alphaBetical =

"aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ";

从这个顺序,我们可以创建一个查找表,看看两个字母应该相互比较.以下函数初始化表,如果还没有首先完成,否则执行表查找.

int alphaBeta_lookup (int c) {

static int initialized;

static char table[CHAR_MAX+1];

if (!initialized) {

/* leave all non-alphaBeticals in their relative order, but below

alphaBeticals */

int i, j;

for (i = j = 1; i < CHAR_MAX+1; ++i) {

if (strchr(alphaBetical, i)) continue;

table[i] = j++;

}

/* now run through the alphaBeticals */

for (i = 0; alphaBetical[i]; ++i) {

table[(int)alphaBetical[i]] = j++;

}

initialized = 1;

}

/* return the computed ordinal of the provided character */

if (c < 0 || c > CHAR_MAX) return c;

return table[c];

}

使用这个查找表,我们现在可以简化alphaBetize()比较函数的循环体:

int alphaBetize (const char *a, const char *b) {

int ax = alphaBeta_lookup(*a);

int bx = alphaBeta_lookup(*b);

int weight = 0;

do {

char al = tolower(*a);

char bl = tolower(*b);

if (ax != bx) {

if (al != bl) {

return alphaBeta_lookup(al) - alphaBeta_lookup(bl);

}

if (weight == 0) {

weight = ax - bx;

}

}

ax = alphaBeta_lookup(*++a);

bx = alphaBeta_lookup(*++b);

} while (ax && bx);

/* if the words compared equal, use the weight as tie breaker */

return (ax != bx) ? !bx - !ax : weight;

}

我们可以让事情更简单吗?

使用整理表,您可以使用简化的比较功能创建许多不同的排序,如:

int simple_collating (const char *a, const char *b) {

while (alphaBeta_lookup(*a) == alphaBeta_lookup(*b)) {

if (*a == '\0') break;

++a, ++b;

}

return alphaBeta_lookup(*a) - alphaBeta_lookup(*b);

}

使用这个相同的功能,通过修改alphaBetical字符串,你可以实现几乎任何你想要的排序(按字母顺序排列,按字母顺序排列,辅音前的元音等).然而,保持一致的单词的安排需要散布大写字母的小写字母,这只能通过做一个比较忽略的情况来完成.

请注意,使用上面的simple_collat​​ing()函数和我提供的alphaBetical字符串,培根将会在牛奶之前,但是火星会在牛奶之后和牛奶之前.

如果要根据您的区域设置进行排序.

如果要使用已为您的区域设置定义的整理顺序,可以设置区域设置并调用整理比较功能:

/*

* To change the collating locale, use (for example):

setlocale(LC_COLLATE, "en.US");

*/

int iso_collating (const char *a, const char *b) {

return strcoll(a, b);

}

现在,通过更改区域设置,排序顺序将基于标准化的整理顺序.

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/651163
推荐阅读
相关标签
  

闽ICP备14008679号