简体   繁体   中英

I need to make a program that will print characters in a word on how frequent it is used

I need to make a program that will print characters in a word on how frequent it is used. The unique characters will be printed in increasing order (spaces are ignored), if there are ties the character with lower ascii value will be printed first.

For an example if the input is hello world, the letters "h", "e", "w", "r" and "d" are only used once, the character "o" is used twice and the character "l" is used thrice. Since h,e,w,r,d are tie we should sort it into d,e,h,r,w. Then next would be o since it is used twice and then last is l. Thus if the input is hello world the output must be dehrwol. On my current program the problem is that when there are ties, it would not sort it alphabetically so the output is hewrdol instead of dehrwol.

This is the code I have written

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

int times[256];

int cmpLetters(const void* a, const void* b)

{

return (times[*(char*)a] > times[*(char*)b]) - (times[*(char*)a] < times[*(char*)b]);

}

int main()

{

char letters[256];

int i, j, k, lnum, t;

char s[1000];


fgets(s, sizeof(s), stdin);

// Init occurrences as 0

memset(times, 0, sizeof(times));

for (i = lnum = 0; s[i] != '\0'; i++)

if (times[s[i]]++ == 0)

letters[lnum++] = s[i];

// Sort letters by number of occurrences

qsort(letters, lnum, sizeof(char), cmpLetters);

char* new = malloc(sizeof(char) * (i + 1));

for (j = k = 0; j < lnum; j++)

for (i = 0; i < times[letters[j]]; i++)

new[k++] = letters[j];

// new[k] = '\0';

for (i = 0; i<lnum; i++)

{

if(letters[i] != '\n' && letters[i] !=' ')

printf("%c",letters[i]);

}

printf("\n\n");



return 0;

}

In this for loop

for (i = lnum = 0; s[i] != '\0'; i++)

if (times[s[i]]++ == 0)

letters[lnum++] = s[i];

you are not checking whether s[i] represents a letter.

The comparison function

int cmpLetters(const void* a, const void* b)

{

return (times[*(char*)a] > times[*(char*)b]) - (times[*(char*)a] < times[*(char*)b]);

}

compares only characters without comparing also their frequencies.

This code snippet

char* new = malloc(sizeof(char) * (i + 1));

for (j = k = 0; j < lnum; j++)

for (i = 0; i < times[letters[j]]; i++)

new[k++] = letters[j];

does not make sense because the array new is not used further in the program. It only produces a memory leak.

The program will be simpler if to introduce a structure that contains two data members that store a letter and its frequency.

Here is a demonstration program.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct Pair
{
    char c;
    size_t n;
};

int cmp( const void *a, const void *b )
{
    const struct Pair *p1 = a;
    const struct Pair *p2 = b;

    int result = ( p2->n < p1->n ) - ( p1->n < p2->n );

    if (result == 0)
    {
        result = ( p2->c < p1->c ) - ( p1->c < p2->c );
    }

    return result;
}

int main( void )
{
    enum { N = 1000} ;
    char s[N];

    fgets( s, sizeof( s ), stdin );

    size_t n = 0;

    for (size_t i = 0; s[i] != '\0'; ++i)
    {
        if (isalpha( ( unsigned char )s[i] ))
        {
            size_t j = 0;

            while (j != i && s[j] != s[i]) ++j;

            n += j == i;
        }
    }

    if (n != 0)
    {
        struct Pair pairs[n];
        memset( pairs, 0, n * sizeof( struct Pair ) );

        for (size_t i = 0, m = 0; s[i] != '\0'; i++)
        {
            if (isalpha( ( unsigned char )s[i] ))
            {
                size_t j = 0;

                while (j != m && pairs[j].c  != s[i]) ++j;

                if (j == m)
                {
                    pairs[m].c = s[i];
                    ++pairs[m].n;
                    ++m;
                }
                else
                {
                    ++pairs[j].n;
                }
            }
        }

        qsort( pairs, n, sizeof( *pairs ), cmp );

        for (size_t i = 0; i < n; i++)
        {
            putchar( pairs[i].c );
        }
        putchar( '\n' );
    }
}

The program output might look like

hello world
dehrwol

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