插入排序C编程-字母



我刚开始学习C,遇到了插入排序算法。我现在正试着把它应用到字母上。然而,我面临的挑战是,我希望程序能够独立地对字母进行分类,而不管它们是否是大写字母。

例如,在排序列表中,'d'应该出现在'E'之前。以下是我目前所掌握的信息。

谢谢你的帮助。

#include <stdio.h>
#define MAX_NUMS 10
void InsertionSort(char list[]);
int main()
{
int index = 0;              /* iteration variable          */
char letters[MAX_NUMS];  /* list of number to be sorted */
/* Get input */
printf("Enter a word: ");
scanf("%s", letters);
printf("%sn", letters);
InsertionSort(letters);  /* Call sorting routine       */
printf("pass");
/* Print sorted list */
printf("nThe input set, in ascending order:n");
while (letters[index] != '') {
printf("%cn", letters[index]);
index += 1;
}
/* printf("%s", letters);
for (index = 0; index < MAX_NUMS; index++)
printf("%cn", letters[index]); */
}
void InsertionSort(char list[])
{
int unsorted;         /* index for unsorted list items */
int sorted;           /* index for sorted items        */
char unsortedItem;     /* Current item to be sorted     */
char lowUnsortedItem;
/* This loop iterates from 1 thru MAX_NUMS  */
for (unsorted = 0; list[unsorted] != ''; unsorted++) {
unsortedItem = list[unsorted];
if (unsortedItem >= 'A' && unsortedItem <= 'Z') {
lowUnsortedItem = unsortedItem + 32;
}
/* This loop iterates from unsorted thru 0, unless
we hit an element smaller than current item */
for (sorted = unsorted - 1;
(sorted >= 0) && (list[sorted] > unsortedItem);
sorted--)
list[sorted + 1] = list[sorted];
list[sorted + 1] = unsortedItem; /* Insert item      */
}
}

我认为你需要从ctype.h中使用tolower()来获得每个字符的小写变体,然后比较这些小写变体。即:

lowUnsortedItem = tolower(unsortedItem)
...
for ( ...; tolower(list[sorted]) > lowUnsortedItem)
...

改进答案我之前的尝试包含一个错误,不包括(后来的)要求,例如,A应该出现在a之前。因此,我已经重写了我的答案。

因为我们有一个比"小于"更复杂的排序条件;根据ASCII字符集,让我们编写一个排序函数和一个返回两个字符是否被正确排序的函数(下面的函数isLessThan),从而使代码更加模块化。如果,在后面的阶段,我们想比较不同的类型或使用不同的排序,我们可以简单地使用不同的比较函数。另外,我们也可以将这个比较函数与另一个排序算法一起使用。另外,参见C标准库的qsort,它使用了类似的模块化方法。

使用布尔值,包括stdbool.h头。使用库函数来检测字符是大写还是小写,并在两者之间进行切换会更方便。因此,包含ctype.h。注意,这些函数接受int!请确保只给它们字符作为输入,否则它们的行为是未定义的。

修改后的代码片段:

bool isLessThan(char lhs, char rhs)
{
if (tolower(lhs) == tolower(rhs))
return isupper(lhs) || islower(rhs);
return tolower(lhs) < tolower(rhs);
}
void InsertionSort(char list[])
{
for (size_t unsortedIdx = 1U; list[unsortedIdx] != ''; ++unsortedIdx)
{
char unsortedItem = list[unsortedIdx];
size_t sortedIdx = unsortedIdx;
for ( ; sortedIdx > 0U && !isLessThan(list[sortedIdx - 1U], unsortedItem); --sortedIdx)
list[sortedIdx] = list[sortedIdx - 1U];
list[sortedIdx] = unsortedItem; // Insert item
}
}

比较函数首先检查我们想要的特殊属性,例如Aa之前。否则,我们将确保两个字符都是小写的,并对它们进行比较。

插入排序算法现在只包含"插入排序逻辑"。为了适应使用无符号类型size_t作为索引,所使用的索引已经做了一些修改,这是一个很好的实践。

一些额外的建议:scanf可能是不安全的w.r.t.缓冲区溢出。最好用fgetssscanf代替。

最新更新