【问题标题】:How can I sort an array of strings (2D Array) alphabetically?如何按字母顺序对字符串数组(二维数组)进行排序?
【发布时间】:2013-07-19 09:00:24
【问题描述】:

我已经有一个从文本文件读入到名为word 的二维数组中的字符串列表,准备好进行排序。

列表如下:

I
like
cherry
pie
and
chocolate
pie

我希望列表在排序后看起来像这样:

and
cherry
chocolate
I
like
pie
pie

函数原型如下。 int counter 是字符串的数量,MAX_CHAR_LEN = 1024 如果您想知道的话。

void alphabetize(char word[][MAX_CHAR_LEN], int counter)
{

    return;
}

请注意,仅按第一个字符排序是不够的,因为列表包含两个以“ch”开头的字符串

有人可以提供可以做到这一点的功能吗?提前致谢。

【问题讨论】:

    标签: c arrays function sorting alphabetical


    【解决方案1】:

    您想使用qsort() 函数。

    qsort(base, num_of_elements, element_size, my_compare);
    

    比较函数my_compare 接受两个参数,每个参数一个const void *,并返回一个表示参数相对顺序的数字。负数表示第一个参数在第二个参数之前。正数表示第一个参数在第二个参数之后。如果参数比较相等,则返回零。

    由于您的字符串比较不区分大小写,因此您需要创建自己的比较函数,或者找到您的系统提供给您的不属于 C 库的一部分。 POSIX 为此提供了strcasecmp()(Google 告诉我_stricmp() 在Windows 上可用)。

    int my_compare (const void *a, const void *b) {
        return strcasecmp(a, b);
    }
    

    定义比较函数通常是使用qsort() 时最棘手的部分。您必须了解传递给该函数的指针的上下文。当TYPE 的数组传入qsort() 时,它会将指向const TYPE 的指针传递给比较函数的每个参数。

    在您的情况下,您将传入MAX_CHAR_LENchars 的数组数组。因此,比较函数的每个参数都是指向MAX_CHAR_LENchars 的常量数组的指针。这意味着从技术上讲,my_compare 函数应该这样写:

    int my_compare (const void *a, const void *b) {
        typedef char TYPE[MAX_CHAR_LEN];
        const TYPE *aa = (const TYPE *)a;
        const TYPE *bb = (const TYPE *)b;
        return strcasecmp(*aa, *bb);
    }
    

    通常不需要对参数进行强制转换,除非 C 并不真正支持 常量数组 的概念。它将这样的东西转换成一个常量数组,因此需要强制转换来反映这一点。

    但是,数组的地址等于其第一个元素的地址。也就是说,对于上面的代码,以下断言是正确的:

        assert(aa == (const void *)*aa);
        assert(bb == (const void *)*bb);
    

    因此,因为指向数组的指针的取消引用等于同一数组的衰减地址值,所以 my_compare() 的第一个实现对于您的二维数组来说已经足够了。

    【讨论】:

    • 为什么会发出警告:warning: initialization discards 'const' qualifier from pointer target type [enabled by default],当演员从分配 const TYPE *aa = a; 中删除时?
    • @hacks:这在答案中my_compare() 代码块下的文本中进行了解释。
    • 那么,根本就不能用const char (*aa)[MAX_CHAR_LEN] = (const char (*)[MAX_CHAR_LEN])a; const char (*bb)[MAX_CHAR_LEN] = (const char (*)[MAX_CHAR_LEN])a;来完成吗?
    • @hacks:我看不出这有多简单,但你可以随心所欲地做。
    • @hacks:没有语法来表达一个常量数组,这就是为什么你找不到任何关于它的原因。 qsort() 不知道它正在排序的数组的实际类型是什么,它传递了一个const void *,其中void 代表正在排序的对象。您所说的衰减发生在qsort() 被传递给数组以进行排序之前或之前。
    【解决方案2】:

    qsort 是不错的选择。查看详情here

    你也可以试试Bubble Sort。它在 C 中的实现很简单 - 请参阅此 Good answer 以获取帮助

    【讨论】:

      【解决方案3】:

      如果您想编写自己的排序函数,类似这样的方法非常简单。

      for (int i = 0; i < array.size(); i++)
      {
          for (int j = i+1; j < array.size(); j++)
          {
              if (array[i] > array[j])
                  swap(array[i],array[j]);
          }
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用qsort 函数进行排序。您还需要创建一个比较两个字符数组的比较函数,然后将该函数指针作为参数传递。

        对整数进行排序的示例:

        /* qsort example */
        #include <stdio.h>      /* printf */
        #include <stdlib.h>     /* qsort */
        
        int values[] = { 40, 10, 100, 90, 20, 25 };
        
        int compare (const void * a, const void * b)
        {
          return ( *(int*)a - *(int*)b );
        }
        
        int main ()
        {
          int n;
          qsort (values, 6, sizeof(int), compare); 
          for (n=0; n<6; n++)
             printf ("%d ",values[n]);
          return 0;
        }
        

        上面的代码可以很容易地用于对字符数组而不是整数进行排序。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-28
          相关资源
          最近更新 更多