2
Input char a[10] = {'c','b','c','d','E','C','a','A','b','C'};

Output : A a b b C C c c d e

I have been given a character array and I have to sort it in ascending order and I must use Counting sort to do that

I have tried so far:

#include <stdio.h>
#include <stdlib.h>
#define RANGE 255


void countingSort(char a[], char b[], int n) // a = array, b = empty array, n = size
{
    int i;

    int c[RANGE +1];
    memset(c, 0, sizeof(c));


    for( i = 0; i< n; i++)
    {
        c[a[i]] = c[a[i]] + 1;
    }
    for(i = 1; i<RANGE; i++)
    {
        c[i] = c[i] + c[i-1];
    }
    for(i = n-1; i>=0; i--)
    {
        b[c[a[i]] - 1] = a[i];
        c[a[i]] = c[a[i]] - 1;
    }

}

int main()
{
    char a[10] = {'c','b','c','d','E','C','a','A','b','C'};
    int n = 10;
    char b[10];
    int i;
    for( i = 0; i<n;i++)
    {
        printf("%c",a[i]);
    }
    printf("\n");
    countingSort(a,b,n);
    for( i = 0; i<n;i++)
    {
        printf("%c",b[i]);
    }
    printf("\n");

    return 0;
}

I have used ASCII table to sort the array and my output is

ACCEabbccd

I managed to sort the array in ascending order but I DO NOT know how to put a right after A and so on.

2
  • Must countingSort() be used unedited and than apply code after calling countingSort() OR can countingSort() change? Commented Apr 28, 2020 at 14:13
  • countingSort() can be edited but it has to be in the program. Actually we are learning counting sort algorithm in class, so we need to implement it in the code. Commented Apr 28, 2020 at 14:17

1 Answer 1

1

One approach simply doubles the c[] size and forms an index where all even indexes are uppercase and odd ones are lowercase.

#if 1
#define RANGE (255*2 + 1)
#include <ctype.h>
#define CH_TO_INDEX(ch) \
    (2*toupper((unsigned char)ch) + !!islower((unsigned char) ch))

#else
// Original
#define RANGE 255
#define CH_TO_INDEX(ch)    (ch)

#endif

void countingSort(char a[], char b[], int n) {
  int i;
  int c[RANGE + 1];
  memset(c, 0, sizeof(c));

  for (i = 0; i < n; i++) {
    //c[a[i]] = c[a[i]] + 1;
    c[CH_TO_INDEX(a[i])]++;
  }
  for (i = 1; i < RANGE; i++) {
    c[i] = c[i] + c[i - 1];
  }
  for (i = n - 1; i >= 0; i--) {
    // b[c[a[i]] - 1] = a[i];
    b[c[CH_TO_INDEX(a[i])] - 1] = a[i];
    // c[a[i]] = c[a[i]] - 1;
    c[CH_TO_INDEX(a[i])]--;
  }
}

Output

cbcdECaAbC
AabbCCccdE

A more complex char --> index could be had that does not double the size of c[]. Such mappings tend to make assumptions that there are only letters A-Z. Such a mapping may use an auxiliary mapping array:

unsigned char map[256] - {
    0, 1, 2, ...., 31, ' ', ... 'A', 'a', 'B', 'b', ... 'Z', 'z', 
    ASCII characters after 'Z' and before 'a'
    ASCII characters after 'z', .... 255 };

OP requested

Output : A a b b C C c c d e

But based on {'c', 'b', 'c', 'd', 'E', 'C', 'a', 'A', 'b', 'C'}, I think OP wants

Output : A a b b C C c c d E

Note that original code fails when a[i] < 0. Code needs re-work for negative char. Re-code using unsigned char.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.