hi, i have C exam next week, so i started solving questions from previous years exams and run into this question, the answer i come up to is far far from having reasonable length, it's too complicated and long , but i can't come up anything shorter.
the question is: write a function that receives an array of letters , and a pointer to final result string that hasn't allocated yet, the function supposed to take the array of letters and count the appearance of every letter and make the final result string look like that:
received array of letters : "abbacdeefg"
result string: "a 2;b 2;c 1;d 1;e 2;f 1;g 1"
in the result it should be alphabetically printed
here is the code that i wrote, it just doesn't makes sense that this is the actual solution:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
void sortarray(char str[],char * final)
{
int i = 1,j, extra = 0;
char * letters, *lerrptr;
int * count, * cerrptr;
int size = 0, flag = 0;
// allocate memory for one array storing letter and one for storing it's appearance
letters = (char *) malloc(sizeof(char) * 1);
if(letters == NULL) exit(1);
count = (int *) malloc(sizeof(int) * 1);
if(count == NULL) exit(1);
// fill the first letter to array
letters[0] = str[0];
count[0] = 1;
size++;
// scan the whole string
while(str[i] != 0)
{
// initiate flag for new run
flag = 0;
for(j = 0 ; j < size ; j++)
{
// if the letter already appeared before just increment the count and raise the flag that no new allocating is necessary
if(str[i] == letters[j])
{
count[j]++;
flag = 1;
}
}
// if the flag of already appeared hasn't been raised make new allocation for new letter
if(!flag)
{
flag = 0 ;
size++;
lerrptr = letters;
letters = (char *) realloc(letters,sizeof(char) * size);
if(letters == NULL)
{
free(lerrptr);
free(count);
exit(1);
}
cerrptr = count;
count = (int *) realloc(count,sizeof(int) * size);
if(letters == NULL)
{
free(cerrptr);
free(letters);
exit(1);
}
// insert new letter and 1 for the count
letters[size-1] = str[i] ;
count[size-1] = 1 ;
}
i++;
}
// bubble sort the letters
for(i = 0 ; i < size - 1; i++)
{
for(j = 0 ; j < size - 1 - i ; j++)
{
if(letters[j] < letters[j - 1])
{
letters[j] ^= letters[j+1];
letters[j+1] ^= letters[j];
letters[j] ^= letters[j+1];
count[j] ^= count[j+1];
count[j+1] ^= count[j];
count[j] ^= count[j+1];
}
}
}
// check for more 9 appearances to reserve more letters for one more digit
for(i = 0 ; i < size ; i++) if(count[i] > 9) extra++;
// allocate the memory for the final array that is going to be printed
final = (char *) malloc(sizeof(char) * (size * 4) + extra + 1);
j = 0;
for(i = 0 ; i < size ; i++)
{
// insert the letter
final[i*4 + j] = letters[i];
// insert space
final[i*4 + 1 + j] = ' ';
// if more then one digit used for the count of appearances
if(count[i] > 9)
{
// first digit
final[i*4 + 2 + j] = count[i]/10 + 48;
j++;
// second
final[i*4 + 2 + j] = count[i]%10 + 48 ;
}
else final[i*4 + 2 + j] = count[i] + 48;
// print ;
final[i*4 + 3 + j] = ';';
}
// add terminating character
final[i*4 + j] = 0;
// print the result
printf(" %s ", final);
}
|
can anyone help me come up with more reasonable solution?