简体   繁体   中英

C program to take a string as input a count the character with the lowest frequency

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:

  • do you want your program to be case sensitive? Leave the program as it is.
  • do you want your program to be case insensitive ? You will have to convert the input chars to lower case (or to upper case; it is your choice) before comparing them
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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM