【问题标题】:sorting by length with stability in c在c中稳定地按长度排序
【发布时间】:2026-01-24 14:55:02
【问题描述】:

我正在处理一个编码问题,我必须按单词的长度对单词数组(指向字符串的指针)进行排序。我对使用一些索引操作的代码有一个想法,但希望在检查逻辑方面得到一些帮助,看看我是否有这个权利。这是我到目前为止的代码。

void len_sort(char** words, int num_words)
{
    int index=0;
    int isSorted=0;
    int string1_len;
    int string2_len;
    while(isSorted==0)
    {
        for(index=0;index<num_words;index++)
        {
            printf("%s\n", words[index]);
            string1_len=strlen(words[index]);
            if((index+1)==num_words)
                string2_len=strlen(words[index]);
            else
                string2_len=strlen(words[index+1]);

            if(string1_len<string2_len)
            {
                swap(words[index], words[index+1]);
            }
        }

        isSorted=1;

        for(index=0;index<num_words;index++)
        {
            string1_len=strlen(words[index]);
            if(index+1==num_words)
                string2_len=strlen(words[index]);
            else
                 string2_len=strlen(words[index+1]);
            if(string1_len>string2_len)
            {
                isSorted=0;
            }
        }

    }


}
void swap(char* word1, char* word2)
{

    char* temp;
    word1=word2;
    word2=temp;

}

我不需要按字母顺序排序,我需要保持单词在数组中的顺序。例如:如果我有类似的东西

car
x
horse
a

我的输出应该是这样的:

x
a
car
horse

保持 x 在数组中 a 之前的事实为真。 有没有更好的方法来提高效率?

【问题讨论】:

  • 您需要重新排序实际内存,还是可以使用指针?
  • 另外,您在寻找什么样的复杂性?
  • 这段代码不正确,因为swap() 几乎什么都不做。
  • 哦,我应该传入数组并在进行交换时通过引用它们来交换数组的值吗?
  • 我对时间复杂性 atm 并不挑剔。也许稍后我会尝试重新设计 O(N) 。我可以使用指针,保存单词的数组是指针数组 (char**) 还是指向字符串的指针数组?我想我应该这么说

标签: c arrays algorithm sorting string-length


【解决方案1】:

交换函数没有做任何有意义的事情。如果要交换两个指针,应该是这样的:

void swap(char **word1, char **word2)
{
    char *temp;

    temp = *word1;
    *word1 = *word2;
    *word2 = temp;

}

现在,为了稳定排序,我们只能在前一个很长的情况下交换下一个。每次交换后,数组将再排序一步。我们从头开始

void len_sort(char** words, int num_words)
{
    int i = 0; //start from the beginning.
    while(i < num_words-1) //till the last pair.
    {
        if(strlen(words[i]) > strlen(words[i+1])){//if a mismatch occur
            swap(&words[i], &words[i+1]);//fix it
            i = -1;//and start from the beginning 
        }
        i++;//so far sorted, try next pair
    }
}

测试:

int main()
{
    char d[][30] = {"car", "x", "horse", "a"};
    char *s[4];
    int i;

    //our function sort through pointer
    for(i=0; i<4; i++)
        s[i] = d[i];

    len_sort(s, 4);
    for(i=0; i<4; i++)
        printf("%s ", s[i]);
    puts("");

    return 0;
}

输出:

x a car horse

【讨论】:

    【解决方案2】:

    您可以使用组合合成键排序,例如:

    uint32_t key = (strlen(s) << 16) | line_no;
    

    【讨论】:

      【解决方案3】:

      我有一个建议。你为什么不创建一对整数,第一个作为你的长度,第二个作为你的字符串索引。然后对它们进行排序。

      这是我的代码:

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      typedef struct {
        int first;
        int second;
      } pair;
      
      int cmp(pair a, pair b){
        return (a.first > b.first) || ((a.first == b.first) && (a.second > b.second));
      }
      
      // you can use your favorite sort algorithm
      // Since in some condition, quick_sort runs in O(n^2)
      void quick_sort (pair *a, int n) {
          int i, j;
          pair p, t;
          if (n < 2)
              return;
          p = a[n / 2];
          for (i = 0, j = n - 1;; i++, j--) {
              while (cmp(a[i],p))
                  i++;
              while (cmp(p,a[j]))
                  j--;
              if (i >= j)
                  break;
              t = a[i];
              a[i] = a[j];
              a[j] = t;
          }
          quick_sort(a, i);
          quick_sort(a + i, n - i);
      }
      
      char** len_sort(char** words, int num_words){
        pair my_pairs[num_words];
      
        // iterate in O(n)
        for (int i = 0; i < num_words; ++i) {
          my_pairs[i].first = strlen(words[i]);
          my_pairs[i].second = i;
        }
      
        // sort in O(nlogn)
        quick_sort(my_pairs, num_words);
      
        // iterate through sorted and create ne wlist of words in O(n)
        char** new_word_list = (char**) malloc(num_words*sizeof(char*));
        for (int i = 0; i < num_words; ++i)
          new_word_list[i] = words[my_pairs[i].second];
      
        return new_word_list;
      }
      

      【讨论】:

      • IIRC,快速排序不是稳定的,如:*.com/questions/1517793/… 你可以使用合并排序。或者,我只是被你称它为“quick_sort”而感到厌烦?
      • 是的,你可以使用任何一种排序算法,我只是想强调解决它们的逻辑。只需将其替换为合并排序或任何类型的排序即可。