如何按字母顺序对字符串数组进行排序(区分大小写,非标准排序规则)

我需要ac语言代码来排序一些字符串,它应该区分大小写, 对于大写和小写的相同字母,小写必须首先 。 例如,以下字符串的排序结果:

eggs bacon cheese Milk spinach potatoes milk spaghetti 

应该:

 bacon cheese eggs milk Milk potatoes spaghetti spinach 

我写了一段代码,但结果是:

 Milk bacon cheese eggs milk potatoes spaghetti spinach 

我不知道如何改进这个,我已经搜索了很多。 任何人都可以帮我这个吗?

 #include  #include  int main(){ char c; char name[20][10], temp[10]; int count_name = 0; int name_index = 0; int i, j; while ((c = getchar()) != EOF){ if (c == 10){ name[count_name][name_index] = '\0'; count_name++; name_index = 0; } else { name[count_name][name_index] = c; name_index++; } } for(i=0; i < count_name-1 ; i++){ for(j=i+1; j 0) { strcpy(temp,name[i]); strcpy(name[i],name[j]); strcpy(name[j],temp); } } } for (i = 0; i < count_name; i++){ printf("%s\n", name[i]); } } 

保持相似的话语……

对于单词列表,将“相同”单词组合在一起通常更有用(即使它们在大小写上有所不同)。 例如:

 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 

避免在字符串上进行两次传递

有时候,现有function的表现不够好,你必须做些其他事情来加快速度。 以下函数在单次传递中以大致相同的方式进行比较,并且不使用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; } 

使用这种比较进行分类将使milkMilk保持彼此相邻,即使该列表包含milk-duds

使用整理表

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

您可以映射字母表的字母与一种简单表格的比较,该表格描述了您希望字母(或除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; } 

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

使用整理表,您可以使用简化的比较function创建许多不同的顺序,例如:

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

使用相同的function并通过修改alphaBetical字符串,您几乎可以实现任何所需的顺序(按字母顺序,反向字母顺序,辅音之前的元音等)。 然而,将类似单词保持在一起的安排需要在大写字母中加入大写单词,这只能通过进行忽略大小写的比较来完成。

请注意,使用上面的simple_collating()函数和我提供的alphaBetical字符串, Bacon将在milk之前出现,但Mars将在milk之前和Milk之前进行。

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

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

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

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

您可以编写自定义比较函数进行排序。

首先,查看默认的strcmp排序顺序:

 #include  #include  #include  #include  const char *tgt[]={ "bacon", "Bacon", "mIlk", "Milk", "spinach", "MILK", "milk", "eggs" }; int tgt_size=8; static int cmp(const void *p1, const void *p2){ return strcmp(* (char * const *) p1, * (char * const *) p2); } int main(int argc, char *argv[]) { printf("Before sort:\n\t"); for(int n=0; n 

strcmp按ASCII字符代码排序; 即,它对AZ进行排序,然后对AZ进行排序,因此所有资本AZ都出现在任何带有小写字母的单词之前:

 Before sort: bacon Bacon mIlk Milk spinach MILK milk eggs After sort: Bacon MILK Milk bacon eggs mIlk milk spinach 

我们可以在qsort中使用的cmp使用我们自己的比较函数来忽略大小写。 看起来像这样:

 int mycmp(const char *a, const char *b) { const char *cp1 = a, *cp2 = b; for (; toupper(*cp1) == toupper(*cp2); cp1++, cp2++) if (*cp1 == '\0') return 0; return ((toupper(*cp1) < toupper(*cp2)) ? -1 : +1); } 

一定要将cmp更改为:

 static int cmp(const void *p1, const void *p2){ return mycmp(* (char * const *) p1, * (char * const *) p2); } 

忽略版本的案例现在打印:

 Before sort: bacon Bacon mIlk Milk spinach MILK milk eggs After sort: bacon Bacon eggs Milk MILK milk mIlk spinach 

这与POSIX函数strcasecmp的输出相同。

函数mycmp首先按正常顺序按字典顺序进行比较[a|A]-[z|Z] 。 这意味着你会得到像字母一样的字母,但你可能会得到bacon, BaconBacon, bacon 。 这是因为qsort不是一个稳定的排序 ,'培根'比较等于'培根'。

现在我们想要的是如果比较为0而忽略大小写(即,像“牛奶”和“牛奶”这样的同一个词)现在比较包括大小写并反转顺序:

 int mycmp(const char *a, const char *b) { const char *cp1 = a, *cp2 = b; int sccmp=1; for (; toupper(*cp1) == toupper(*cp2); cp1++, cp2++) if (*cp1 == '\0') sccmp = 0; if (sccmp) return ((toupper(*cp1) < toupper(*cp2)) ? -1 : +1); for (; *a == *b; a++, b++) if (*a == '\0') return 0; return ((*a < *b) ? +1 : -1); } 

最终版本打印:

 Before sort: bacon Bacon mIlk Milk spinach MILK milk eggs After sort: bacon Bacon eggs milk mIlk Milk MILK spinach 

不幸的是,这种方法对UNICODE来说变得难以处理。 对于复杂排序,请考虑使用具有稳定排序的映射或多步排序 。

对于复杂和位置感知的字母排序规则,请考虑Unicode排序规则 。 例如,在不同的位置,字母按字母顺序不同:

 Swedish z < ö y == w German ö < z Danish Z < Å Lithuanian i < y < k Tr German ä == æ Tr Spanish c < ch < d German Dictionary Sort: of < öf German Phonebook Sort: öf < of 

默认Unicode排序规则元素表( DUCET )中捕获这些区别的默认值,该表为UNICODE排序规则和字符串比较提供默认映射。 您可以修改默认值以捕获字典排序和电话簿排序,不同位置或案例的不同处理之间的区别。 在Unicode公共区域设置数据存储库( CLDR )中主动跟踪各个位置变体。

多级排序的推荐是分层的:

 Level Description Examples L1 Base characters role < roles < rule L2 Accents role < rôle < roles L3 Case/Variants role < Role < rôle L4 Punctuation role < “role” < Role Ln Identical role < ro□le < “role” 

ICU库中广泛使用的Unicode排序规则实现。 几个示例的默认DUCET排序规则是:

 b < B < bad < Bad < bäd c < C < cote < coté < côte < côté 

您可以使用ICU Explorer浏览 ICU库并更改位置和目标

如果您想为giggles实现自己的DUCET版本,可以按照此Python脚本中使用的常规方法进行操作。 这不是压倒性的,但不是微不足道的。

OP代码的关键是使用函数strcmp()来比较两个字符串。
因此,我将从另一个替换此标准函数开始,如下所示:

  // We assume that the collating sequence satisfies the following rules: // 'A' < 'B' < 'C' < ... // 'a' < 'b' < 'c' < ... // We don't make any other assumptions. #include  int my_strcmp(const char * s1, const char * s2) { const char *p1 = s1, *p2 = s2; while(*p1 == *p2 && *p1 != '\0' && *p2 != '\0') p1++, p2++; /* keep searching... */ if (*p1 == *p2) return 0; if (*p1 == '\0') return -1; if (*p2 == '\0') return +1; char c1 = tolower(*p1), c2 = tolower(*p2); int u1 = isupper(*p1) != 0, u2 = isupper(*p2) != 0; if (c1 != c2) return c1 - c2; // <<--- Alphabetical order assumption is used here if (c1 == c2) return u1 - u2; } 

最后一行可以这样压缩:

  return (c1 != c2)? c1 - c2: u1 - u2; 

现在,通过my_strcmp()替换strcmp() ,您将获得所需的结果。

在排序算法中,最好分别考虑它的3个主要方面:

  • 比较函数。
  • 我们将使用的抽象排序算法。
  • 当必须交换两个项目时,数据中的方式将在数组中“移动”。

这些方面可以独立优化。
因此,例如,一旦你的比较函数得到很好的解决,下一个优化步骤可能是用更高效的算法替换double for sort算法,比如quicksort
特别是,标准库的函数qsort()为您提供了这样的算法,因此您无需关心它的编程。
最后,用于存储arrays信息的策略可能会对性能产生影响。
将字符串存储为“char指针数组”而不是“char数组数组”会更高效,因为交换指针比交换两个整个字符数组更快。

指针数组

附加注意:前三个if()实际上是多余的,因为在*p1*p2为0的情况下,下列句子的逻辑意味着所需的结果。但是,通过保留那些if() ,代码变得更具可读性。

在这里,如果我做对了,你想要的东西如我所描述的如下:

不区分大小写的排序,在tie,tiebreaker条件“小写第一”的情况下使用。

所以它就像:

  1. earlier_letter_in_the_alphabet < later_letter_in_the_alphabet忽略了这个案子

  2. lowercase < uppercase

  3. shorter_word < wider_word
    • 没有提到这一点,我是从字典顺序中借用它,字典中的那个
    • 只需将'\0'作为比较中的最低值即可使用

只有当1没有区分时才采取步骤2。 步骤3已经用1进行检查。所有这些都是逐字母完成的,这意味着一旦你在相应的字符之间取得平局就应该切换到2,而不是在整个字符串处于平局时。


假设这是正确的,我们现在需要做的就是编写一个函数,对任何给定的两个字符串进行比较。

 #include  // for tolower and islower int my_character_compare(const char a, const char b) { int my_result; my_result = tolower(a) - tolower(b); // unless it is zero, my_result is definitely the result here // Note: if any one of them was 0, result will also properly favour that one if (my_result == 0 && a != b) // if (could not be distinguished with #1, but are different) { // means that they are case-insensitively same // but different... // means that one of them are lowercase, the other one is upper if (islower(a)) return -1; // favour a else return 1; // favour b } // regardless if zero or not, my_result is definitely just the result return my_result; } int my_string_compare(const char * a, const char * b) { int my_result; my_result = my_character_compare(*a, *b); // unless it is zero, my_result is definitely the result here while (my_result == 0 && *a != 0) // current characters deemed to be same // if they are not both just 0 we will have to check the next ones { my_result = my_character_compare(*++a, *++b); } // whatever the my_result has been: // whether it became != zero on the way and broke out of the loop // or it is still zero, but we have also reached the end of the road/strings return my_result; } 

按惯例/规则,比较函数应返回负值以使第一个参数位于前面,负值表示支持第二个参数,如果不能区分它们则返回零。 您可能已经通过使用strcmp的方式获得的其他信息。

就是这样! 用my_string_compare替换你的代码中的strcmp ,同时提出我们在顶部做的这些定义应该提供正确的结果。 实际上,它为所讨论的示例输入提供了预期结果。

人们可以缩短当然的定义,我已经做了很长时间,以便更容易理解正在发生的事情。 例如,我可以将其全部归结为以下内容:

 #include  int my_string_compare(const char * a, const char * b) { int my_result; while (*a || *b) { if ((my_result = tolower(*a) - tolower(*b))) return my_result; if (*a != *b) return (islower(*a)) ? -1 : 1; a++; b++; } return 0; } 

与另一个基本相同,你可以使用你喜欢的任何一个; 甚至更好,写一个。

我迟到了这个讨论,并没有特别期望天鹅和获得神话般的奖品,但没有看到使用我首先看到的习语的解决方案,我想我会插话。

我在阅读问题规范时的第一个想法是某种forms的自定义整理顺序,我基本上在@jxh的使用整理表概念中找到了。 我不认为不区分大小写是一个核心概念,只是奇怪的订单。

所以,我提供以下代码纯粹作为替代实现。 它特定于glibc – qsort_r(3)被使用 – 但感觉就像一个更轻量级的方法,并在运行时支持许多整理序列。 但它经过了轻微的测试,我很可能会错过各种各样的弱点。 其中:我没有特别注意Unicode或一般的宽字符世界,并且为了避免负数组下标而转换为unsigned char感到可疑。

 #include  #include  /* * Initialize an index array associated with the collating * sequence in co. The affected array can subsequently be * passed in as the final client data pointer into qsort_r * to be used by collating_compare below. */ int collating_init(const char *co, int *cv, size_t n) { const unsigned char *uco = (const unsigned char *) co; const unsigned char *s; size_t i; if (n <= UCHAR_MAX) { return -1; } for (i = 0; i < n; i++) { /* default for chars not named in the sequence */ cv[i] = UCHAR_MAX; } for (s = uco; *s; s++) { /* * the "collating value" for a character's own * character code is its ordinal (starting from * zero) in the collating sequence. Ie, we * compare the values of cv['a'] and cv['A'] - * rather than 'a' and 'A' - to determine order. */ cv[*s] = (s - uco); } return 0; } static int _collating_compare(const char *str1, const char *str2, int *ip) { const unsigned char *s1 = (const unsigned char *) str1; const unsigned char *s2 = (const unsigned char *) str2; while (*s1 != '\0' && *s2 != '\0') { int cv1 = ip[*s1++]; int cv2 = ip[*s2++]; if (cv1 < cv2) return -1; if (cv1 > cv2) return 1; } if (*s1 == '\0' && *s2 == '\0') { return 0; } else { return *s1 == '\0' ? -1 : 1; } } int collating_compare(const void *v1, const void *v2, void *p) { return _collating_compare(*(const char **) v1, *(const char **) v2, (int *) p); } 

前面的代码可以放在单独的模块或库中,但缺少自己的头文件(或头文件中的条目)。 我自己的测试只是将上面和下面的代码连接到一个名为custom_collat​​e_sort.c的文件中,并使用

 gcc -DMAIN_TEST -Wall -o custom_collate_sort custom_collate_sort.c 

……编译它。

 #if defined(MAIN_TEST) /* qsort_r is a GNU-ey thing... */ #define __USE_GNU #include  #include  #define NELEM(x) (sizeof x / sizeof 0[x]) static int cmp(const void *v1, const void *v2) { return strcmp(*(const char **) v1, *(const char **) v2); } static int casecmp(const void *v1, const void *v2) { return strcasecmp(*(const char **) v1, *(const char **) v2); } int main(int ac, char *av[]) { size_t i; int cval[256], ret; int cval_rev[256], rret; char *tosort[] = { "cheeSE", "eggs", "Milk", "potatoes", "cheese", "spaghetti", "eggs", "milk", "spinach", "bacon", "egg", "apple", "PEAR", "pea", "berry" }; ret = collating_init("aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVxXyYzZ", cval, NELEM(cval)); rret = collating_init("ZzYyXxVvUuTtSsRrQqPpOoNnMmLlKkJjIiHhGgFfEeDdCcBbAa", cval_rev, NELEM(cval_rev)); if (ret == -1 || rret == -1) { fputs("collating value array must accomodate an index of UCHAR_MAX\n", stderr); return 1; } puts("Unsorted:"); for (i = 0; i < NELEM(tosort); i++) { printf(" %s\n", tosort[i]); } qsort((void *) tosort, NELEM(tosort), sizeof tosort[0], cmp); puts("Sorted w/ strcmp:"); for (i = 0; i < NELEM(tosort); i++) { printf(" %s\n", tosort[i]); } qsort((void *) tosort, NELEM(tosort), sizeof tosort[0], casecmp); puts("Sorted w/ strcasecmp:"); for (i = 0; i < NELEM(tosort); i++) { printf(" %s\n", tosort[i]); } qsort_r((void *) tosort, NELEM(tosort), sizeof tosort[0], collating_compare, (void *) cval); puts("Sorted w/ collating sequence:"); for (i = 0; i < NELEM(tosort); i++) { printf(" %s\n", tosort[i]); } qsort_r((void *) tosort, NELEM(tosort), sizeof tosort[0], collating_compare, (void *) cval_rev); puts("Sorted w/ reversed collating sequence:"); for (i = 0; i < NELEM(tosort); i++) { printf(" %s\n", tosort[i]); } return 0; } #endif /* MAIN_TEST */ 

程序要求的标准头文件:

 #include  #include  #include  

主程序从这里开始:

 //Global Variables Required //========= const char *tgt[]={"bacon", "Bacon", "mIlk", "Milk", "spinach", "MILK", "milk", "eggs"}; //Array for sorting int tgt_size=8; //Total Number of Records int SortLookupTable[128]; //Custom sorting table typedef int cmp_t (const void *, const void *); int main(int argc, char *argv[]) { printf("Before sort:\n\n"); int n=0; for(n=0; n 

根据需要自定义排序表:

 void CreateSortTable(void){ int i; for (i = 0; i < 128; i++){ SortLookupTable[i] = 0; } char *s; s=(char *)malloc(64); memset(s, 0, 64); strcpy(s, "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"); i=1; for (; *s; s++){ SortLookupTable[(int) ((unsigned char) *s)]=i; i++; } } 

快速排序算法,您也可以使用标准库提供:

 //Some important Definations required by Quick Sort ======= #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; #define swap(a, b) \ if (swaptype == 0) { \ long t = *(long *)(a); \ *(long *)(a) = *(long *)(b); \ *(long *)(b) = t; \ } else \ swapfunc(a, b, es, swaptype) #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) #define swapcode(TYPE, parmi, parmj, n) { \ long i = (n) / sizeof (TYPE); \ register TYPE *pi = (TYPE *) (parmi); \ register TYPE *pj = (TYPE *) (parmj); \ do { \ register TYPE t = *pi; \ *pi++ = *pj; \ *pj++ = t; \ } while (--i > 0); \ } #define min(a, b) (a) < (b) ? a : b //Other important function void swapfunc(char *a, char *b, int n, int swaptype){ if(swaptype <= 1) swapcode(long, a, b, n) else swapcode(char, a, b, n) } char * med3(char *a, char *b, char *c, cmp_t *cmp){ if ( cmp(a, b) < 0){ if (cmp(b, c) < 0){ return b; }else{ if ( cmp(a, c) < 0){ return c; }else{ return a; } } }else{ if (cmp(b, c) < 0){ return b; }else{ if ( cmp(a, c) < 0){ return a; }else{ return c; } } } } //Custom Quick Sort void myQsort(void *a, unsigned int n, unsigned int es, cmp_t *cmp){ char *pa, *pb, *pc, *pd, *pl, *pm, *pn; int d, r, swaptype, swap_cnt; loop: SWAPINIT(a, es); swap_cnt = 0; if (n < 7) { for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0; pl -= es){ swap(pl, pl - es); } return; } pm = (char *)a + (n / 2) * es; if (n > 7) { pl = a; pn = (char *)a + (n - 1) * es; if (n > 40) { d = (n / 8) * es; pl = med3(pl, pl + d, pl + 2 * d, cmp); pm = med3(pm - d, pm, pm + d, cmp); pn = med3(pn - 2 * d, pn - d, pn, cmp); } pm = med3(pl, pm, pn, cmp); } swap(a, pm); pa = pb = (char *)a + es; pc = pd = (char *)a + (n - 1) * es; for (;;) { while (pb <= pc && (r = cmp(pb, a)) <= 0) { if (r == 0) { swap_cnt = 1; swap(pa, pb); pa += es; } pb += es; } while (pb <= pc && (r = cmp(pc, a)) >= 0) { if (r == 0) { swap_cnt = 1; swap(pc, pd); pd -= es; } pc -= es; } if (pb > pc) break; swap(pb, pc); swap_cnt = 1; pb += es; pc -= es; } if (swap_cnt == 0) { /* Switch to insertion sort */ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0; pl -= es) swap(pl, pl - es); return; } pn = (char *)a + n * es; r = min(pa - (char *)a, pb - pa); vecswap(a, pb - r, r); r = min(pd - pc, pn - pd - es); vecswap(pb, pn - r, r); if ((r = pb - pa) > es) myQsort(a, r / es, es, cmp); if ((r = pd - pc) > es) { /* Iterate rather than recurse to save stack space */ a = pn - r; n = r / es; goto loop; } } 

两个最重要的function是:

 unsigned char Change(char a){ return (unsigned char ) SortLookupTable[(int)a]; } int compare (const void *a, const void *b){ char *s1= *(char **)a; char *s2= *(char **)b; int ret, len, i; ret=0; if (strlen((void*)s1) > strlen((void*)s2)){ len=strlen((void*)s1); }else{ len=strlen((void*)s2) ; } for(i=0; i