0

I'm writing a code a that prompts the user to enter a string

&

create a function that is a type void that prints out the character that was used the most

(As in where it appeared more than any other ones)

&

also shows the number of how many times it was in that string.

Therefore here is what I have so far...

#include <stdio.h>
#include <string.h>
/* frequent character in the string along with the length of the string (use strlen from string.h – this will require you to #include <string.h> at the top of your program).*/


/* Use array syntax (e.g. array[5]) to access the elements of your array.
 * Write a program that prompts a user to input a string, 
 * accepts the string as input, and outputs the most
 * You should implement a function called mostfrequent.
 * The function prototype for mostfrequent is: void mostfrequent(int *counts, char *most_freq, int *qty_most_freq, int num_counts);
 * Hint: Consider the integer value of the ASCII characters and how the offsets can be translated to ints.
 * Assume the user inputs only the characters a through z (all lowercase, no spaces). 
 */


void mostfrequent(int *counts, char *most_freq, int *qty_most_freq, int num_counts_)
{
        int array[255] = {0}; // initialize all elements to 0
        int i, index;
        for(i = 0; most_freq[i] != 0; i++)
        {
           ++array[most_freq[i]];
        }
// Find the letter that was used the most

qty_most_freq = array[0];
 for(i = 0; most_freq[i] != 0; i++)
 {
      if(array[most_freq[i]] > qty_most_freq)
           {
               qty_most_freq = array[most_freq[i]];
               counts = i;
           }
        num_counts_++;
}
  printf("The most frequent character was: '%c' with %d occurances \n", most_freq[index], counts);
        printf("%d characters were used \n",  num_counts_);
}
int main()
{
char array[5];
printf("Enter a string ");
scanf("%s", array);
int count = sizeof(array);
mostfrequent(count , array, 0, 0);
        return 0;
}

I'm getting the wrong output too.

output:

Enter a string hello The most frequent character was: 'h' with 2 occurances 5 characters were used

should be

The most frequent character was: 'l' with 2 occurances 5 characters were used

Adan Vivero
  • 422
  • 12
  • 36
  • Please fix the indentation of your code. It is not readable as it is. – Eugene Sh. Sep 30 '19 at 19:30
  • @EugeneSh. I did control k, I don't know if this is better. – Adan Vivero Sep 30 '19 at 19:33
  • Please address all your compiler warnings. That will clean up most of your issues. If you are using gcc the -Wall option will be useful. – jmq Sep 30 '19 at 19:41
  • @jmq I am getting the wrong numbers on my output. I'll list them down. – Adan Vivero Sep 30 '19 at 19:43
  • the third parameter of your mostfrequent function is declared as a pointer to an int but you only refer it as a normal variable.... – nobur Sep 30 '19 at 19:44
  • How could I fix it? I struggle with pointers.. – Adan Vivero Sep 30 '19 at 19:47
  • Read [this](https://stackoverflow.com/questions/57842756/why-should-i-always-enable-compiler-warnings). – n. m. could be an AI Sep 30 '19 at 20:00
  • first in your mostfrequent function, you must refer to the pointed value not the pointer itself by preceding the variable name with a star (*) like *qty_most_freq = array[0]; then pass a pointer to a var on your function call int result = 0; mostfrequent(count , array, &int, 0); – nobur Sep 30 '19 at 20:11
  • Solve a simpler problem: given a string, create a histogram of the character count in that string, and print them out. – Neil Sep 30 '19 at 20:36
  • "create a function that is a type `void` that ***returns*** the character that was used the most" OXYMORON. – David C. Rankin Sep 30 '19 at 20:40
  • I didn't noticed before that you're also misusing pointet on first and last parameters. the first parameters is suposed to be a pointer to an int but you pass the int itself on the call. If you don't need your int variables to be updated in your main fonction don't use pointers , it's useless. moreover, for the 3rd and 4th param, if you don't need to pass a specific value, just declare them locally in your function. – nobur Sep 30 '19 at 21:00
  • @nobur declare them locally as ints? – Adan Vivero Sep 30 '19 at 21:56
  • yes! for int *qty_most_freq are int num_counts_ you pass a static 0 value from main. it's a bit useless. why don't you just create 2 ints in your function initialized with 0. – nobur Sep 30 '19 at 22:11
  • 1
    ok ! i didn't notice the comments... is that school homeworks? if yes! try to modify your code by yourself using my answer. just don't forget: if your function waits for a pointer (int *qty_most_freq) you can't feed it with a value (0) . you have to create a variable and pass a pointer to it ( with &). In the function, you can read the pointed value using a star prefix (*var) – nobur Sep 30 '19 at 22:38
  • @nobur I've figured it out. Thanks for your help. – Adan Vivero Oct 02 '19 at 00:31

3 Answers3

1

let's do it short (others will correct me if I write something wrong ^_^ ) you declare a int like this:

int var;

use it like this :

var = 3;

you declare a pointer like this :

int* pvar;

and use the pointed value like this:

*pvar = 3;

if you declared a variable and need to pass a pointer to it as function parameters, use the & operator like this :

functionA(&var);

or simply save its address in a pointer var :

pvar = &var;

that's the basics. I hope it will help...

nobur
  • 144
  • 4
1

The function prototype you are supposed to use seems to include at least one superfluous parameter. (you have the total character count available in main()). In order to find the most frequently appearing character (at least the 1st of the characters that occur that number of times), all you need to provide your function is:

  1. the character string to be evaluated;
  2. an array sized so that each element represents on in the range of values you want to find the most frequent (for ASCII characters 128 is fine, for all in the range of unsigned char, 256 will do); and finally
  3. a pointer to return the index in your frequency array that holds the index to the most frequently used character (or the 1st character of a set if more than one are used that same number of times).

In your function, your goal is to loop over each character in your string. In the frequency array (that you have initialized all zero), you will map each character to an element in the frequency array and increment the value at that element each time the character is encountered. For example for "hello", you would increment:

frequency['h']++;
frequency['e']++;
frequency['l']++;
frequency['l']++;
frequency['o']++;

Above you can see when you are done, the element frequency['l']; will hold the value of 2. So when you are done you just loop over all elements in frequency and find the index for the element that holds the largest value.

if (frequency[i] > frequency[most])
   most = i;

(which is also why you will get the first of all characters that appear that number of times. If you change to >= you will get the last of that set of characters. Also, in your character count you ignore the 6th character, the '\n', which is fine for single-line input, but for multi-line input you need to consider how you want to handle that)

In your case, putting it altogether, you could do something similar to:

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

enum { CHARS = 255, MAXC = 1024 };      /* constants used below */

void mostfrequent (const char *s, int *c, int *most)
{
    for (; *s; s++)     /* loop over each char, fill c, set most index */
        if (isalpha (*s) && ++c[(int)*s] > c[*most])
            *most = *s;
}

int main (void) {

    char buf[MAXC];
    int c[CHARS] = {0}, n = 0, ndx;

    /* read all chars into buf up to MAXC-1 chars */
    while (n < MAXC-1 && (buf[n] = getchar()) != '\n' && buf[n] != EOF)
        n++;
    buf[n] = 0;     /* nul-terminate buf */

    mostfrequent (buf, c, &ndx);    /* fill c with most freq, set index */
    printf ("most frequent char: %c (occurs %d times, %d chars used)\n",
            ndx, c[ndx], n);
}

(note: by using isalpha() in the comparison it will handle both upper/lower case characters, you can adjust as desired by simply checking upper/lower case or just converting all characters to one case or another)

Example Use/Output

$ echo "hello" | ./bin/mostfreqchar3
most frequent char: l (occurs 2 times, 5 chars used)

(note: if you use "heello", you will still receive "most frequent char: e (occurs 2 times, 6 chars used)" due to 'e' being the first of two character that are seen the same number of times)

There are many ways to handle frequency problems, but in essence they all work in the same manner. With ASCII characters, you can capture both the most frequent character and the number of times it occurs in a single array of int and an int holding the index to where the max occurs. (you don't really need the index either -- it just save looping to find it each time it is needed).

For more complex types, you will generally use a simple struct to hold the count and the object. For example if you were looking for the most frequent word, you would generally use a struct such as:

struct wfreq {
    char *word;
    int count;
}

Then you simply use an array of struct wfreq in the same way you are using your array of int here. Look things over and let me know if you have further questions.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
0

Here is what I came up with. I messed up with the pointers.

void mostfrequent(int *counts, char *most_freq, int *qty_most_freq, int num_counts_)
{
        *qty_most_freq = counts[0];
        *most_freq = 'a';
        int i;
 for(i = 0; i < num_counts_; i++)
 {

      if(counts[i] > *qty_most_freq)
           {
               *qty_most_freq = counts[i];
               *most_freq = 'a' + i;
           }
}
}
/* char string[80]
 * read in string
 * int counts[26]; // histogram
 * zero counts (zero the array)
 * look at each character in string and update the histogram
 */
int main()
{
int i;
int num_chars = 26;
int counts[num_chars];
char string[100];

/*zero out the counts array */
 for(i = 0; i < num_chars; i++)
 {
        counts[i] = 0;
 }
printf("Enter a string ");
scanf("%s", string);

for(i = 0; i < strlen(string); i++)
{
        counts[(string[i] - 'a')]++;
}

int qty_most_freq;
char most_freq;

mostfrequent(counts , &most_freq, &qty_most_freq, num_chars);
printf("The most frequent character was: '%c' with %d occurances \n", most_freq, qty_most_freq);
        printf("%d characters were used \n",  strlen(string));
        return 0;
}
Adan Vivero
  • 422
  • 12
  • 36
  • 1
    good to hear. just a small tips to shorten your code: your can zero an array during declaration just with one line - > char string[100] = {0}; – nobur Oct 03 '19 at 01:30