【问题标题】:Can't alphabetize(sort) strings? [closed]不能按字母顺序排列(排序)字符串? [关闭]
【发布时间】:2020-01-31 05:27:09
【问题描述】:

所以我使用插入排序来对字符串进行排序。 如果字符串已经排序,它将运行。如果它们被部分排序或完全颠倒。它要么运行产生不正确的结果,要么给出错误:(0xC0000005)

ptr 声明:char **ptr; 其中内存是动态分配的。

插入排序:

 void insertionSort(char **ptr,int rows,int cols)
{
   char *key;
   int i,j;

   //first element is considered sorted 

   for( i=1;i<=rows-1;i++)
   {
      key=ptr[i];
      for( j=i-1;strcmp(key,ptr[j])<0 && j>=0;j--)
      {
         ptr[j+1]=ptr[j];
      }
      /*Program sometimes stalls at this part and gives error:`(0xC0000005)` 
      when strings are partially sorted/completely reversed*/
      ptr[j + 1] = key;
   }
}

这是您非常标准的插入排序实现。适用于数字,所以我不知道为什么我不能对字符串进行排序。

这也是ptr 的值是如何从用户那里定义的:

void read_charArray(char **ptr,int rows,int cols)
{
   for(int i=0;i<=rows-1;i++)
   {
      printf("Enter name for name #%-3d: ",i+1);
      fgets(ptr[i],cols+5,stdin);
      ptr[i]=strtok(array[i],"\n");
   }
}

【问题讨论】:

  • 请发minimal reproducible example 来展示您所描述的内容。
  • 只是一点点小提示,这里的人喜欢代码可读而不需要水平滚动,特别是如果代码还需要垂直滚动;当你做出适当的 MRE 时,你会这样做。
  • 如何定义传递给该函数的数组?
  • @Yunnosch 这样好吗?
  • 仍然没有定义数组。我的意思是,在你的main 中,你可能有类似char array[X][Y] 的东西,我也想看看那部分

标签: c string sorting insertion-sort


【解决方案1】:

错误在于程序插入部分的第二个for()循环:

插入排序:

 void insertionSort(char **ptr,int rows,int cols)
{
   char *key;
   int i,j;

   //first element is considered sorted 

   for( i=1;i<=rows-1;i++)
   {
      key=ptr[i];
      for( j=i-1;strcmp(key,ptr[j])<0 && j>=0;j--)
      {
         ptr[j+1]=ptr[j];
      }
      /*Program sometimes stalls at this part and gives error:`(0xC0000005)` 
      when strings are partially sorted/completely reversed*/
      ptr[j + 1] = key;
   }
}

j 递减到低于 0 时,尽管存在 j&gt;=0 表达式(基本上 短路。参见https://softwareengineering.stackexchange.com/a/201899 )-->这意味着您正在尝试访问超出范围的内存(未分配给程序),从而导致错误:(0xC0000005)

此错误:(0xC0000005) 表示“您访问了您无权使用的内存”,例如,滥用了不够大的指针或数组等。

要纠正这个问题,您只需将for( j=i-1; strcmp(key,ptr[j])&lt;0 &amp;&amp; j&gt;=0;j--) 中的条件表达式切换为for( j=i-1; j&gt;=0 &amp;&amp; strcmp(key,ptr[j])&lt;0;j--)

这样做是在j 递减到低于0 的那一刻,程序测试j&gt;=0 first 从而退出循环而不是导致错误。

【讨论】:

  • 很好地解决了这个问题。始终牢记随着数据集的增长,简单的排序变得越来越低效,例如Time Comparison of Quick Sort, Insertion Sort and Bubble Sort。其他排序,如 bottom_up 合并排序和快速排序(分治算法),按数量级执行冒泡和插入排序。
  • 我们是否可以只对大多数种情况使用合并排序,因为它似乎是最有效的?
  • 是的,但请确保您使用的是 Bottom_Up Iterative 合并排序而不是 Top_Down 纯递归合并排序或用于大型数据集,由于递归函数调用,您将耗尽堆栈空间。 Merge sort - Wikipedia 很好地解释了这两种算法。
  • iterative/recursive分别被称为Bottom_Up/Top_Down有什么原因吗? PS:说到算法,你了解算法的一般概念,只是复制粘贴算法的模板吗?
  • 当我将非惯用的 for( i=1;i&lt;=rows-1;i++) 阅读为 for( i=1;i&lt;=rows;i++) 时,我的阅读错误。考虑 1) for( i=1;i&lt;rows;i++),因为它是 C 惯用的并且更易于阅读。 2) minimal reproducible example 很有帮助 - 它也鼓励投票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
相关资源
最近更新 更多