逻辑挑战:在C中按字母顺序排序数组

时间:2013-08-23 17:29:13

标签: c algorithm sorting strcmp

我是编程的新手,目前正在学习C.我已经在这个问题上工作了一个星期了,而我似乎无法直接理解逻辑。这直接来自我正在使用的书:

  

构建一个使用字符串数组存储以下名称的程序:

     
      
  • “佛罗里达”
  •   
  • “俄勒冈”
  •   
  • “Califoria”
  •   
  • “格”
  •   
     

使用前面的字符串数组,编写自己的sort()函数,使用strcmp()函数按字母顺序显示每个州的名称。

所以,让我说我有:

char *statesArray[4] = {"Florida", "Oregon", "California", "Georgia"}; 

我是否应该嵌套for循环,例如strcmp(string[x], string[y])...?我已经入侵并砍掉了。我只是无法绕过解决这个问题所需的算法,甚至有效。帮助很多人赞赏!!!

6 个答案:

答案 0 :(得分:6)

想象你必须对数组进行排序 - 想想写在卡片上的每个状态。你会把它按顺序排序吗?有很多方法可以做到这一点。每一个都称为算法

一种方法是通过查看每张卡片并在您看到的最低卡片的头部保持跟踪来找到第一个状态。看完每张卡后你会得到最低的一张。把它放在一堆新的。没有重复 - 试图找到你剩下的最低的。

重复直到原始桩中没有卡片

这是一个众所周知的简单但缓慢的算法。这是我先做的那个

还有其他的

答案 1 :(得分:5)

是的,您可以使用嵌套for循环进行排序。在了解了strcmp()如何工作之后,它应该是相当直接的:

  

strcmp(char * string1,char * string2)

     
      
  • 如果返回值为< 0,则表示string1小于string2

  •   
  • 如果返回值为> 0,则表示string2小于string1

  •   
  • 如果返回值为= 0,则表示string1等于string2
  •   

然后,您可以从此处选择任何一种排序方法

This site有很多正在执行的各种类型的图形示例,包括给定算法的伪代码。

答案 2 :(得分:3)

您应该采取的步骤:

  1. 使用州名填充数组
  2. 创建方法以在数组中交换两个状态
  3. 此时,您拥有使用strcmp实现您选择的任何排序算法所需的所有工具
  4. 大多数排序方法都依赖于两件事。

    1. 能够重新排列列表(即交换)
    2. 能够比较列表中的项目以查看是否应该交换
    3. 我会努力让这两件事情正常工作,其余的应该只是学习一种特定的排序算法

答案 3 :(得分:3)

您是否需要“任何”排序算法或“高效”排序算法?

为简单起见,我可以向您展示如何实现一种简单但不高效的排序算法。 这是double for方法!! 然后,使用相同的想法,您可以将其修改为任何其他有效的算法(如shell或quicksort)。

对于数字,您可以按顺序放置数组,如下所示(您可能知道):

int intcmp(int a, int b) {
    return (a < b)? -1: ((a > b)? +1: 0);
}

int main(void) {
   int a[5] = {3, 4, 22, -13, 9};

   for (int i = 0; i < 5; i++) {
      for (int j = i+1; j < 5; j++)
         if (intcmp(a[i], a[j]) > 0) {
            int temp = a[i]; 
            a[i] = a[j]; 
            a[j] = temp; 
         }
       printf("%d ", a[i]);
   }
}

现在唯一改变的是你有整数字符串整数。 所以,你必须考虑一个字符串数组:

 char *a[] = {"Florida", "Oregon", "Califoria", "Georgia"};

然后,您必须将temp的类型更改为char*
最后你把函数strcmp()代替intcmp()

  

函数strcmp(s1, s2)(来自&lt; string.h&gt;)   返回一个数字&lt; 0如果s1是字符串“小于”s2,则== 0如果s1是   “等于”s2,&gt; 1其他。

程序如下:

#include <stdio.h>
#include <string.h>
int main(void) {
   char *a[] = {"Florida", "Oregon", "Califoria", "Georgia"};

   for (int i = 0; i < 4; i++) {
      for (int j = i+1; j < 4; j++)
         if (strcmp(a[i], a[j]) > 0) {
            char* temp = a[i]; 
            a[i] = a[j]; 
            a[j] = temp; 
         }
       printf("%s ", a[i]);
     }
   getchar();
   return 0;  
}

请注意,对于printf()句子,我们已将"%d "更改为"%s ",以便正确显示字符串。

最终评论 当您编写更好的算法(如快速排序)时,只需更改比较算法就足够了,因为算法是相同的,尽管您正在比较的数据类型。

备注: 我使用过“棘手”的方法。如您所见,我已将变量a定义为 指向字符串 的指针。初始化器采用了一个常量的字符串数组,然后用它初始化变量a。现在可以安全地处理变量a并将其编入索引为4个指针到字符串的数组 这就是为什么“swap”在double-for算法中正常工作的原因:内存地址被交换而不是整个字符串。

答案 4 :(得分:1)

请注意一些小问题:字符串按ascii数字表示法排序,因此如果按字母顺序排序,任何大写字母都会出现在小写字母之前,例如&#34; alpha&#34;,&#34; beta&#34;,&#34; gamma&#34;,&#34; Theta&#34;将分类为: Theta,alpha,beta,gamma

答案 5 :(得分:0)

对于您在此处列出的示例数组,前面提到的简单算法实际上可能效率最高。我所指的算法是你从第一个元素开始然后将它与其他元素进行比较并用你找到的最小元素替换然后转到下一个元素来做同样的算法而不将它与已经排序的比较元素。

虽然该算法的执行时间为O(n ^ 2)。其中n是数组中元素的数量。对于较小的数组,它通常比快速排序(执行时间O(n * log(n))更快。原因是快速排序有更多的开销。对于更大的数组,快速排序将比其他方法更好地服务于你,如果记忆对我来说是正确的,那就称为替代排序,虽然我在另一个答案中看到它被称为“双重”。