【问题标题】:Insertion sort C programming - alphabet letters插入排序 C 编程 - 字母
【发布时间】:2021-08-21 16:11:20
【问题描述】:

我刚开始学习 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("%s\n", letters);

  InsertionSort(letters);  /* Call sorting routine       */

  printf("pass");

  /* Print sorted list */
  printf("\nThe input set, in ascending order:\n");
  while (letters[index] != '\0') {
    printf("%c\n", letters[index]);
    index += 1;
  }
  /* printf("%s", letters);
 for (index = 0; index < MAX_NUMS; index++)
    printf("%c\n", 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] != '\0'; 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      */
  }
}

【问题讨论】:

  • 'd' 应该在'D' 之前还是之后?还是说"dX" 会在"DY" 之前出现?
  • 'D' 会出现在 'd' 之前。请注意,该程序不会比较两个不同的字符串。如果您有任何问题,请告诉我。

标签: c insertion-sort


【解决方案1】:

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

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

【讨论】:

  • 感谢您的回复。它对我意义重大。我从应用经济背景切换到 CS。这是我新旅程的开始。
  • 没关系。如果你想学习编程——多练习,多写代码。
【解决方案2】:

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

由于我们有一个更复杂的排序条件,而不仅仅是根据 ASCII 字符集的“小于”,让我们通过编写一个排序函数和一个返回两个字符是否正确排序的函数(函数isLessThan 下方)。如果在稍后阶段,我们想比较不同的类型或使用不同的排序,我们可以简单地使用不同的比较函数。或者,我们也可以将此比较函数与另一种排序算法一起使用。此外,请参阅 C 标准库的 qsort,它使用了类似的模块化方法。

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

修改后的代码sn-p:

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] != '\0'; ++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

【讨论】:

  • 感谢您的回复。它对我意义重大。我从应用经济背景切换到 CS。这是我新旅程的开始。
  • @Osslot 不客气。我稍后才阅读订购要求。请看我修改后的答案。
猜你喜欢
  • 1970-01-01
  • 2019-09-02
  • 1970-01-01
  • 2013-01-26
  • 1970-01-01
  • 2020-10-26
  • 2017-10-23
  • 2020-04-16
  • 2012-10-21
相关资源
最近更新 更多