Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In C, sort array of strings by string length

So I input strings into an array mydata[10][81]

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

I then use a for loop to create a second array of pointers

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

This is where I get stuck I know I need to use strlen somehow, but I can't even conceive of how to get the length of a pointer and then re-assign that pointer a new position based on a third additional value of length

Hopefully that makes sense, I'm so lost on how to do it or explain it, I'm just trying to sort strings by length using array positions (not using something like qsort)

I did some more work on it and came up with this: any idea why its not working?

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]);
        }    
} 
like image 825
Knell Avatar asked Nov 18 '14 19:11

Knell


People also ask

Can you use sort () on an array of strings?

To sort an array of strings in Java, we can use Arrays. sort() function.

How do you sort an array by distance?

sort(function(a,b) { return parseFloat(a. distance) - parseFloat(b. distance) } );

How do you sort a string element in an array?

To sort a String array in Java, you need to compare each element of the array to all the remaining elements, if the result is greater than 0, swap them.


2 Answers

As suggested in the comments by Deduplicator, you can use qsort defined in stdlib.h.

#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;
}

You can see it in action over here.

like image 52
Etheryte Avatar answered Sep 20 '22 17:09

Etheryte


To avoid to call several time strlen() on the same strings, you can use a listed chain of structures like following :

#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);
}
like image 21
Wang Avatar answered Sep 20 '22 17:09

Wang