Как посчитать количество одинаковых символов в С? - PullRequest
0 голосов
/ 30 сентября 2019

Я пишу код a, который предлагает пользователю ввести строку

&

создать функцию типа void, которая печатает символ, который использовался чаще всего

(как и там, где оно появилось больше, чем любые другие)

&

также показывает количество раз, которое было в этой строке.

Поэтому вот что у меня есть ...

#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;
}

Я тоже получаю неправильный вывод.

вывод:

Введите строку привет. Наиболее частым символом был: 'h' с 2 случаями. Использовалось 5 символов

должно быть

Наиболеечастым символом было: 'l' с 2 случаями. Использовалось 5 символов

Ответы [ 3 ]

1 голос
/ 01 октября 2019

Кажется, что в используемом вами прототипе функции есть хотя бы один лишний параметр. (у вас есть общее количество символов в main()). Чтобы найти наиболее часто встречающийся символ (по крайней мере, 1-й из символов, встречающихся столько раз), все, что вам нужно для предоставления вашей функции, это:

  1. строка символов, которая должна быть оценена;
  2. размер массива, чтобы каждый элемент представлял в диапазоне значений, который вы хотите найти наиболее часто (для символов ASCII 128 - это хорошо, для всех в диапазоне unsigned char, 256 подойдет);и, наконец,
  3. указатель для возврата индекса в вашем частотном массиве, который содержит индекс для наиболее часто используемого символа (или 1-го символа набора, если более одного используется такое же количество раз).

В вашей функции ваша цель состоит в том, чтобы зацикливаться на каждом символе в вашей строке. В массиве частот (который вы инициализировали всеми нулями) вы будете отображать каждый символ на элемент в массиве частот и увеличивать значение этого элемента каждый раз, когда встречается символ. Например, для "hello" вы должны увеличить:

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

Выше, когда вы закончите, элемент frequency['l']; будет содержать значение 2. Итак, когда вы закончите, вы просто зациклите все элементы по частоте и найдете index для элемента, который содержит наибольшее значение.

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

(именно поэтому вы получите первый из всех символов, которые появляются такое количество раз. Если вы измените на >=, вы получите последний из этого набора символов. Также, впри подсчете количества символов вы игнорируете шестой символ, '\n', что хорошо для однострочного ввода, но для многострочного ввода вам нужно подумать, как вы хотите это обработать)

В вашем случае,говоря в целом, вы можете сделать что-то похожее на:

#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: , с помощью isalpha() в сравнении он будет обрабатывать как символы верхнего, так и нижнего регистра, вы можете настроитьпо желанию, просто проверяя верхний / нижний регистр или просто конвертируя все символы в один или другой регистр)

Пример Использование / Вывод

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

( примечание: если вы используете "heello", вы все равно получите "most frequent char: e (occurs 2 times, 6 chars used)", поскольку 'e' является первым из двух символов, которые встречаются одинаковое количество раз)

Существует много способов обработкипроблемы с частотой, но по сути все ониork таким же образом. С помощью символов ASCII вы можете захватить как наиболее часто встречающийся символ, так и число раз, которое он встречается в одном массиве int и int, содержащих индекс, на котором происходит максимум. (индекс вам на самом деле тоже не нужен - он просто сохраняет циклы, чтобы найти его каждый раз, когда он необходим).

Для более сложных типов вы обычно будете использовать простую структуру для хранения счетчика иобъект. Например, если вы ищете наиболее частое слово , вы обычно используете такую ​​структуру, как:

struct wfreq {
    char *word;
    int count;
}

Тогда вы просто используете массив struct wfreq таким же образомВы используете свой массив int здесь. Посмотрите вещи и дайте мне знать, если у вас есть дополнительные вопросы.

1 голос
/ 30 сентября 2019

давайте сделаем это коротко (другие исправят меня, если я напишу что-то не так ^ _ ^), вы объявляете int следующим образом:

int var;

используйте это так:

var = 3;

вы объявляете указатель следующим образом:

int* pvar;

и используете указанное значение следующим образом:

*pvar = 3;

, если вы объявили переменную и вам нужно передать указатель на нее в качестве параметров функциииспользуйте оператор & следующим образом:

functionA(&var);

или просто сохраните его адрес в указателе var:

pvar = &var;

это основные сведения. Я надеюсь, что это поможет ...

0 голосов
/ 02 октября 2019

Вот что я придумал. Я перепутал с указателями.

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;
}
...