I managed to sort it alphabetically but I need to sort it by the most frequent characters first after that. Since I'm new to C programming Im not sure if this alphabetical sort is needed. Also I thought about using a struct but not sure how to do the whole process with it.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmpfunc(const void *a, const void *b) {
return *(char*)a - *(char*)b;
}
void AlphabetOrder(char str[]) {
qsort(str, (size_t) strlen(str), (size_t) sizeof(char), cmpfunc);
printf("%s\n", str);
}
void Max_Occurring(char *str)
{
int i;
int max = 0;
int freq[256] = {0};
for(i = 0; str[i] != '\0'; i )
{
freq[str[i]] = freq[str[i]] 1;
}
for(i = 0; i < 256; i )
{
if(freq[i] > freq[max])
{
max = i;
}
}
printf("Character '%c' appears %d times", max, freq[max], str);
}
int main() {
char str1[20];
printf("Enter a string: ");
scanf("%s", &str1);
AlphabetOrder(str1);
Max_Occurring(str1);
return 0;
}
CodePudding user response:
I wrote you a frequency sorter using the idea that @WeatherVane mentioned:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct cfreq {
unsigned char c;
int freq;
};
int freqcmp(const void *a, const void *b) {
struct cfreq *a2 = (struct cfreq *) a;
struct cfreq *b2 = (struct cfreq *) b;
if(a2->freq < b2->freq) return -1;
if(a2->freq == b2->freq) return 0;
return 1;
}
int freqcmpdesc(const void *a, const void *b) {
return -freqcmp(a, b);
}
void FrequencyOrder(const char str[]) {
struct cfreq cfreqs[256];
for(int i = 0; i < sizeof(cfreqs) / sizeof(*cfreqs); i ) {
cfreqs[i].c = i;
cfreqs[i].freq = 0;
}
for(int i = 0; str[i]; i ) cfreqs[str[i]].freq ;
qsort(cfreqs, sizeof(cfreqs) / sizeof(*cfreqs), sizeof(*cfreqs), freqcmpdesc);
for(int i = 0; i < sizeof(cfreqs) / sizeof(*cfreqs); i ) {
if(cfreqs[i].freq) printf("%c", cfreqs[i].c);
}
printf("\n");
}
int main() {
char str1[20];
printf("Enter a string: ");
scanf("%s", &str1);
FrequencyOrder(str1);
return 0;
}
and here is a sample session (note: output is not deterministic for letters with same frequency):
Enter a string: buzz
zbu
If you want duplicate letters in the output then replace the print with a loop along these lines:
while(cfreqs[i].freq--) printf("%c", cfreqs[i].c);
CodePudding user response:
Im not sure if this alphabetical sort is needed.
It is not needed, yet if done, Max_Occurring()
can take advantage of a sorted string.
Since the string is sorted before calling Max_Occurring()
, compute the max occurring via a count of adjacent repetitions of each char
.
// Untested illustrative code.
// str points to a sorted string.
void Max_Occurring(const char *str) {
char max_ch = '\0';
size_t max_occurence = 0;
char previous = '\0';
size_t occurrence = 0;
while (*str) {
if (*str == previous) {
occurrence ;
} else {
occurrence = 1;
}
if (occurrence > max_occurence) {
max_occurence = occurrence;
max_ch = *str;
}
previous = *str;
str ;
}
printf("Character '%c' appears %zu times", max_ch, max_occurence);
}
In the case of multiple characters with the same max occurrence, this code only reports one max.
Avoid buffer overflow
Do not use scanf("%s"...
without a width limit.
Tip: enable all warnings to save time and see the problem of using &str1
when str1
should be used.
char str1[20];
...
// scanf("%s", &str1);
scanf("s", str1);