【问题标题】:In C, sort array of strings by string length在 C 中,按字符串长度对字符串数组进行排序
【发布时间】:2015-01-16 03:33:48
【问题描述】:

所以我将字符串输入到数组mydata[10][81]

while ((ct<=10) && gets(mydata[ct]) != NULL && (mydata[ct++][0] != '\0'))

然后我使用 for 循环创建第二个指针数组

for (i=0;i<11;i++){
    ptstr[i] = mydata[i];
}

这是我卡住的地方 我知道我需要以某种方式使用strlen,但我什至无法想象如何获取指针的长度,然后根据长度的第三个附加值重新分配该指针一个新位置

希望这是有道理的,我不知道如何去做或解释它,我只是想使用数组位置按长度对字符串进行排序(而不是使用像 qsort 这样的东西)

我做了更多的工作并想出了这个: 知道为什么它不起作用吗?

void orderLength(char *ptstr[], int num){
int temp;
char *tempptr;
int lengthArray[10];
int length = num;
int step, i, j, u;
for (i=0; i<num;i++){
    lengthArray[i] = strlen(ptstr[i]);
}
for (step=0; step < length; step++){
    for(j = step+1; j < step; j++){
          if (lengthArray[j] < lengthArray[step]){
              temp = lengthArray[j];
              lengthArray[j] = lengthArray[step];
              lengthArray[step] =temp;
              tempptr=ptstr[j];
              ptstr[j]=ptstr[step];

              }
          }
    }
    for (u=0; u<num; u++){
        printf("%s \n", ptstr[u]);
        }    
} 

【问题讨论】:

  • 使用qsort 和基于strlen 的自定义比较器。
  • 您可能想了解qsort 库函数。或者阅读更多关于sorting algorithms的信息。
  • 您打算如何进行排序?使用快速排序(然后按照其他评论的建议)或自己编写代码?而且那个while循环很糟糕——很容易通过读取太长的字符串和读取太多的字符串来破坏内存......而且你的for循环也会从ct数组的末尾开始! (假设您的意思是 mydata,而不是 mystrings)
  • 提示:如果您只是对字符串进行排序,您可以调用strcmp 来比较内容。如果您按长度对它们进行排序,则改为比较长度(比较 strlen 返回的值)
  • 不要使用gets()

标签: c arrays string-length


【解决方案1】:

正如 Deduplicator 在 cmets 中所建议的,您可以使用在 stdlib.h 中定义的 qsort

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ROWS 4
#define MAXLEN 20

int compare (const void * a, const void * b) {
    size_t fa = strlen((const char *)a);
    size_t fb = strlen((const char *)b);
    return (fa > fb) - (fa < fb);
}

int main(int argc, const char * argv[]) {
    char arr[ROWS][MAXLEN] = {
        "abcd",
        "ab",
        "abcdefgh",
        "abc"
    };
    qsort(arr, ROWS, MAXLEN, compare);
    return 0;
}

你可以在over here看到它。

【讨论】:

  • 我怀疑我是否会使用这种表达方式。其意图尚不清楚。
  • 我相信我知道使用(fa &gt; fb) - (fa &lt; fb) 而不是fa - fb 的一个可能原因,那就是如果表达式fa - fb 会导致数字下溢或上溢。所以在 32 位世界中,假设 fa2^31 - 1 并且 fb 是负数 2^31 - 1 那么 fa - fb2^32 - 2 这是一个负数结果,即使 fa 大于 fb。所以我可能不得不收回我所说的关于简化 return 表达式的内容!
  • 我刚刚学到了一些东西,以前没见过这样的回报!
  • @lurker fa, fb 不能为负数。它们的类型是一些无符号整数。只要SIZE_MAX &gt; INT_MAXfa - fb 就永远不会是负数。
  • @chux 明白了。我在考虑其他可能不是基于size_t 的更一般的情况。很抱歉造成混乱。
【解决方案2】:

为避免在同一个字符串上多次调用 strlen(),您可以使用列出的结构链,如下所示:

#include <stdio.h>
#include <stdlib.h>

typedef struct  t_elem
{
    char        data[81];
    int         length;
    t_elem      *next;
};

int     main(int ac, char **av)
{   
    t_elem      *head;
    t_elem      *recent;
    t_elem      *current;

    while (/* string have to be sorted */)
    {
        if (head == NULL) {
            head = (t_elem *)malloc(sizeof(t_elem));
            head->data = //readTheFirstString();
            head->length = strlen(head->data);
            head->next = NULL;
        }
        else {
            recent = (t_elem *)malloc(sizeof(t_elem));
            recent->data = //readTheNextString();
            recent->length = strlen(recent->data);
            recent->next = NULL;

            if (recent->length < head->length) {
                recent->next = head;
                head = recent;
            }
            else {
                current = head;
                while (current->next && current->next->length < recent->length) {
                    current = current->next;
                }
                recent->next = current->next;
                current->next = recent;
            }
        }
    }

    // print the sorted chained list
    current = head;
    while (current->next) {
        printf("%s\n", current->data);
        current = current->next;
    }

    // free the list
    current = head;
    while (current->next) {
        recent = current;
        current = current->next;
        free(recent);
    }
    return (0);
}

【讨论】:

    【解决方案3】:

    一个非常简单的版本可能看起来像这样。这是一个bubble sort,对于任何合理的大小数据来说都非常慢,但看起来你只对 11 个元素进行排序,所以在这里没关系。

    关键是'if'语句,它比较两个数组位置的长度。如果它们有问题,接下来的三行将交换它们。

    char* temp;
    int length = 11;
    int step, i;
    for(step = 0; step < length - 1; step++)
        for(i = 0; i < length - step - 1; i++)
        {
            if(strlen(ptstr[i]) > strlen(ptstr[i+1]))
            {
                temp = ptstr[i];
                ptstr[i] = ptstr[i + 1];
                ptstr[i + 1] = temp;
            }
        }
    

    编辑: 如果要按字符串的内容而不是长度进行排序,请将 if 语句更改为:

    if(strcmp(ptstr[i], ptstr[i + 1]) > 0)
    

    (注意:最好尽可能使用 strncmp)

    【讨论】:

    • if(strcmp(ptstr[i], ptstr[i + 1])) 有点毫无意义:每次字符串不一样时交换字符串。也许你的意思是if(strcmp(ptstr[i], ptstr[i + 1]) &gt; 0)
    【解决方案4】:
    //C program to sort string based on string length.
    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char a[200][200],temp[20];
        int i,j,n;
        printf("Enter no. of strings to be input = ");scanf("%d",&n);
        printf("Enter %d strings:\n",n);
        for(i=0;i<n;i++)
        scanf("%s",&a[i]);
    //Sorting string based on length
        for(i=0;i<n-1;i++)
        {
            for(j=0;j<n-i-1;j++)
            {
                if(strlen(a[j])>strlen(a[j+1]))
                {
                    strcpy(temp,a[j]);
                    strcpy(a[j],a[j+1]);
                    strcpy(a[j+1],temp);
                }
            }
        }
        printf("After Sorting :\n");
        for(i=0;i<n;i++)
        printf("%s\n",a[i]);
        return 0;
    }
    //Made By Capricious Coder; Happy Coding :D
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-04-23
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      • 2021-03-16
      • 2018-03-24
      • 2013-12-03
      • 2012-12-24
      相关资源
      最近更新 更多