I have a C program which is meant to return the repeating characters and their frequencies from a given input string. At the moment, it works fine, however I was wondering if there was a way I could change it so it would return characters in order of appearance, as opposed to alphabetical(?) order.
# include <stdio.h>
# include <stdlib.h>
#include <ctype.h>
# define NO_OF_CHARS 256
char fillCharCounts(unsigned char *str, int *count)
{
int i;
for (i = 0; *(str i); i )
count[*(str i)] ;
return 0;
}
void printDups(unsigned char *str)
{
int *count = (int *)calloc(NO_OF_CHARS,
sizeof(int));
fillCharCounts(str, count);
int dupe_chars = 0;
int i;
for (i = 0; i < NO_OF_CHARS; i )
if (count[i] > 1) {
printf ("\nDuplicate letter: %c, Occurrences: %d", i, count[i]);
dupe_chars;
}
if (0 != dupe_chars)
printf ("\n");
else
printf ("\nNo duplicates found\n");
free(count);
}
int main()
{
unsigned char str[15] = "";
printf("Enter a word>");
scanf("%s", str);
printDups(str);
getchar();
return 0;
}
At the moment, if the input string were say "zzbbaa" it would give the output;
"Duplicate: a, count: 2" "Duplicate: b, count: 2" "Duplicate: z, count: 2"
How can I change this so the output returns the duplicates in order of appearance in the string?
CodePudding user response:
You can go through the string again, printing out the duplicate the first time it's found.
Here's code as I would write it. There's no need for dynamic allocation of memory -- the count
array can go on the stack, and *(str i)
is much better written str[i]
.
#include <stdio.h>
#include <limits.h>
void printDups(unsigned char *s) {
int count[UCHAR_MAX 1] = {0};
int dupes = 0;
for (int i = 0; s[i]; i ) {
count[s[i]] ;
dupes = dupes || (count[s[i]] > 1);
}
for (int i = 0; s[i]; i ) {
if (count[s[i]] > 1) {
printf("Duplicate letter: %c, Occurrences: %d\n", s[i], count[s[i]]);
count[s[i]] = 0;
}
}
if (!dupes) {
printf("No duplicates found\n");
}
}
int main(int argc, char**argv) {
unsigned char s[] = "hello world";
printDups(s);
}