I have writtten this code for finding the character with the minimum frequency.
So, giving in input "We were here"
, the output should be
The letter with the minimum frequency is ‘h’ and the frequency is 1.
but it shows
What is my mistake? I have tried everything but I couldn't find the problem root.
#include <string.h>
int main()
{
char s[1000];
int a[1000],i,j,k,count=0,n;
printf("Enter the string : ");
gets(s);
for(j=0;s[j];j++);
k=n=j;
for(i=0;i<n;i++)
{
a[i]=n;
count=1;
if(s[i])
{
for(j=i+1;j<n;j++)
{
if(s[i]==s[j])
{
count++;
s[j]='\0';
}
}
a[i]=count;
if(count<=k)
k=count;
}
}
printf("The letter with the minimum frequency is ");
for(j=0;j<n;j++)
{
if(a[j]==k)
{
printf(" '%c',",s[j]);
}
}
printf("and the frequency is %d t\n ",k);
return 0;
}
Your program could use several optimizations, but let's focus on the main issue. The least frequent characters input string "We were here"
are actually 'W'
, 'w'
and 'h'
, all of them with a single occurrence.
Your mistake is considering 'W'
and 'w'
as the same character. They're not, as the first is upper case and the second is lower case and they have different representations.
Please note that if the entered string was "we were here"
you would have the expected output:
The letter with the minimum frequency is 'h', and the frequency is 1
Now you have to make a design choice:
if(tolower(s[i]) == tolower(s[j]))
{
count++;
s[j]='\0';
}
tolower()
function converts a single character to lower case (not hte whole string!) and it is defined in ctype.h
.
Note: gets()
function is deprecated and should not be used. It is dangerous because it doesn't provide any check on the number of characters inserted by the user, so that a malicious one could easily make your program crash. You could use fgets
, instead
fgets(s, 1000, stdin);
It reads until \n
or EOF of the input file (in this case stdin) is reached. You will have just to pay attention to the fact that the closing \n
is included in the returned string.
Sorry to say that, but your code is way too complicated for the given simple problem of computing a character histogram. You just need one loop over the string to compute the histogram, plus another loop for determining the minimum afterwards (or keep the minimum count and associated letters while computing the histogram).
Apart from that, the printed result is correct. If you want your count to be case insensitive, you could use tolower
or such.
In C, you can make use of the fact that char
is in fact stored as an int
. The ascii
array below is used to store the frequency of each ASCII character in the input string. If a B
character, ascii[66]
is incremented (ASCII code of B
is 66).
I implemented a simple smallest
function that returns the index of smallest items within the ascii
array. If ascii is {1,9,1,2,3,4,5,6,1,8}
, smallest
would return an array {0, 2, 8}
, with n
and f
set to 3.
Don't use gets()
, which is not safe, instead fgets() does what you want in a safer way.
The code below works for ASCII characters only (anything with an int representation > 127 would cause the program crash).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <ctype.h>
#define LEN 128 /* size of ASCII table */
#define BUFLEN 2048
/* initialized to zero */
int ascii[LEN];
char buf[BUFLEN];
/*
* function to return the index of minimum numbers
* within an int array
* arr - input array
* len - size of the input array
* n - size of the returned array
* f - frequency of the min number
* the caller has to free() the buffer returned by
* this function
*/
int *smallest(int arr[], size_t len, int *n, int *f){
int i, j, *ret, min = INT_MAX;
ret = malloc(len * sizeof(int));
memset(ret, 0, len);
i = 0; /* index within ret */
for (j=0; j<len; j++){
/* update the min value */
if (arr[j] < min && arr[j] != 0) {
min = arr[j];
/* for a new min, start from index 0 */
i = 0;
ret[i++] = j;
continue;
}
if (arr[j] == min)
ret[i++] = j;
}
*f = min;
*n = i; /* number of elements in ret */
return ret;
}
int main(){
int i, f, *p;
printf("Enter the string : ");
fgets(buf, BUFLEN, stdin);
/* use letters as indices in the ascii[] array */
for(i=0; i<BUFLEN; i++)
ascii[tolower(buf[i])]++; /* case-insensitive */
/* we can reuse i */
p = smallest(ascii, LEN, &i, &f);
printf("The letter(s) with the minimum frequency = ");
while(i >= 0){
if (isalpha(p[i]))
printf("'%c', ", p[i]);
i--;
}
printf("and the frequency is %d.\n", f);
free(p);
return 0;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.