Points to know
- You don't need to pass the address of the variable
str
to scanf()
- Don't use
"%s"
, use "%<WIDTH>s"
, to avoid buffer-overflow
- Always check whether
scanf()
conversion was successful or not, by checking its return value
- Always use
size_t
to iterator over any array
i < strlen(str)
, makes the loop's time complexity O(n3), instead of O(n2), which also isn't very good you should check whether str[i] != 0
. But, many modern compilers of C
will optimize it by the way.
#include <Stdio.h>
it is very wrong, stdio.h
!= Stdio.h
- Call to
printf()
can be optimized using puts()
and putc()
without any special formatting, here also modern compiler can optimize it
while(str[k] != '\0')){
has a bracket (')'
)
- Initialize your variable
str
using {}
, this will assign 0
to all the elements of str
Better Implementation
My implementation for this problem is that create a list of character (256 max) with 0 initialized, and then add 1 to ASCII value of the character (from str
) in that list. After that print those character whose value was greater than 1.
Time Complexity = O(n), where n
is the length of the string
Space Complexity = O(NO_OF_CHARACTERS), where NO_OF_CHARACTERS
is 256
Final Code
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
static void print_dup(const char *str)
{
size_t *count = calloc(1 << CHAR_BIT, sizeof(size_t));
for(size_t i = 0; str[i]; i++)
{
count[(unsigned char)str[i]]++;
}
for (size_t i = 0; i < (1 << CHAR_BIT); i++)
{
if(count[i] > 1)
{
printf("`%c`, count = %zu\n", i, count[i]);
}
}
free(count);
}
int main(void) {
char str[51] = {};
puts("Enter string:");
if (scanf("%50s", str) != 1)
{
perror("bad input");
return EXIT_FAILURE;
}
print_dup(str);
return EXIT_SUCCESS;
}