How to sort char array by 1) length and 2) alphabetic order?

1.4k views Asked by At

I am learning C-programming and working on a school assignment. With limited possibilities to ask teachers or peers (due to the Corona-outbreak and distancing at home) I am reaching out to you. Help is much appreciated.

My challenge: To write a program which use different functions to sort 11 text-strings with regards to their length and then alphabetic order. Tell the user what the limits of the program are.

Desired output, for instance:
bc
bcb
bcebc
cbbcac
dbccac
(...)

Firstly, the user must enter 11 text-strings. This I have solved with the following code:

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

#define NUMBER_OF_STRINGS 11


int main (void)

char textstrings[NUMBER_OF_STRINGS][15];
int i;

(...) 

printf("Enter 11 textstrings, one by one:\n");
for(i=0;i<NUMBER_OF_STRINGS-1;i++)
   {
   printf("Enter string %d: ", i + 1);
   gets(textstrings[i]);
   }

Now that we got our strings in "textstrings[i]", they must be sorted, and printed. I think the most good-looking way would be to have separate functions for each sorting condition. E.g. a separate function for "length" and then another for "alphabetic order". I understand that I should use "strlen" to compare length and "strcmp" to compare for alphabetic order.

I also understand that a strategy for sorting by multiple conditions is to write comparison expressions for each of the conditions that returns the appropriate return type of the comparison function, and evaluate them in order of the desired sort order e.g. first length, then alphabetical.

This is where I am lost...

However, I do understand that the logic of ordering by length can look something like this:

char* temp;
int step
int length=20; //Not allowing text longer than 20 characters.

for(step=0;step<length-1;step++)
for(i=0;i<length-step-1;i++)
  {
  if(strlen(textstrings[i])>strlen(textstrings[i+1]))
   {
   temp=textstrings[i];
   textstrings[i]=textstrings[i+1];
   textstrings[i+1]=temp;
   }

And I also understand that sorting according to alphabetic order can look something like this:

int k, m

for(k=0;k<=NUMBER_OF_STRINGS-1;k++)
{
  for(m=k+1;m<=NUMBER_OF_STRINGS-1;m++)
     if(strmcp(textstrings[k], textstrings[m])>0)
     swap(textstrings[k], textstrings[m]);
}

       where a swap function would look like:

      void swap (char *s1, char *s2)
      {
      char tmp[20];
      strcopy(temp,s1);
      strcopy(s1,s2);
      strcopy(s2,temp);
      }

However, I do not know how to write comparison expressions and I don't understand what piece of code that can be kept in the main-function, and what separate functions that are appropriate. An ideal answer would include an example-code to show how this task can be solved, cause I am more than lost!

THANK YOU!

1

There are 1 answers

10
Support Ukraine On

When sorting arrays in C your friend is qsort. All you need to implement is a compare function and then call qsort.

For instance:

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

#define NUMBER_OF_STRINGS 11

int cmplen(const void *p1, const void *p2)
{
    size_t len1 = strlen((const char *) p1);
    size_t len2 = strlen((const char *) p2);
    if (len1 < len2) return -1;
    if (len1 > len2) return  1;
    return 0;
}

int main(int argc, char const *argv[])
{
    char textstrings[NUMBER_OF_STRINGS][15] = {"abcd", "dcg", "htj", "jkler", "qwerty", "zxcvbnm", "a", "aa", "pppp", "lkjh", "ld"};
    qsort(textstrings, NUMBER_OF_STRINGS, sizeof textstrings[0], cmplen);
    for (size_t i = 0; i < NUMBER_OF_STRINGS; ++i) puts(textstrings[i]);
    return 0;
}

Output

a
aa
ld
dcg
htj
abcd
pppp
lkjh
jkler
qwerty
zxcvbnm

In case you want to sort by both length and alphabet with length having highest priority, you can change the compare function to

int cmplen(const void *p1, const void *p2)
{
    size_t len1 = strlen((const char *) p1);
    size_t len2 = strlen((const char *) p2);
    if (len1 < len2) return -1;
    if (len1 > len2) return  1;
    return strcmp((const char *) p1, (const char *) p2);
}

Output

a
aa
ld
dcg
htj
abcd
lkjh
pppp
jkler
qwerty
zxcvbnm

Now the output is sorted by length and for equal length it's sorted alphabetic (notice that "pppp" and "lkjh" swapped position compared to previous code that only sorted by length).

BTW: Don't use gets for getting the input. It's unsafe. Take a look at fgets instead.