Проблема - сортировка символов в строке по частоте - PullRequest
0 голосов
/ 04 октября 2018

Учитывая строку, я пытаюсь подсчитать вхождение каждой буквы в строке, а затем отсортировать их частоту по возрастанию.Затем для писем с одинаковым количеством вхождений я должен отсортировать их в алфавитном порядке.

Подобные случаи были успешными, но я не знаю, как добавить к ним правильную букву алфавита.

Можете ли вы помочь мне, так как я действительно новичок в C?

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

void main() {
  printf("Enter: \n");

  char sifra[10000];
  int pole[26] = {0};
  char pismeno, znak;
  int i;

  int l, max, pomm;
  int m, x, y;
  char abeceda[26] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
      'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'};

  gets(sifra);

  int n = strlen(sifra);

  for (i = 0; i < n; i++) {
    pismeno = tolower(sifra[i]);

    if (pismeno >= 97 && pismeno <= 122) {
      pole[pismeno - 97]++;
    }
  }

  for (i = 97; i <= 122; i++) {
    printf("%c --- %d -times\n", toupper(i), pole[i - 97]);
  }

  //sorting it here

  l = 25;
  do {
    max = 0;
    for (x = 0; x <= l; x++) {
      if (pole[x] > pole[max])
        max = x;
    }

    l--;
  } while (l != 0);

  for (y = 25; y > -1; y--) {
    printf("%c  =  %d, ", toupper(122 - y), pole[y]);
  }
  printf(" \n ");

  return 0;
}

Вывод должен выглядеть примерно так: Z = 15, C = 5, A = 1, B = 1 ...

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Вот возможное решение, которое близко к вашему исходному коду:

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

#define MAXBUF 10000

int main()
{
    printf("Enter: \n");

    char sifra[MAXBUF];
    int pole[26]={0};
    char pismeno, znak;
    int i;

    int  l, max, temp;
    int m, x, y;
    char abeceda[26] = {'A','B','C','D','E','F','G','H','I','J','K','L','M',
       'N','O','P','Q','R','S','T','U','V','W','X','Y','Z'};

    fgets(sifra, MAXBUF, stdin);

    int n=strlen(sifra);
    for(i=0; i<n; i++)
    {
        pismeno= tolower(sifra[i]);
        if(pismeno>=97 && pismeno<=122)
        {
            pole[pismeno-97]++;
        }
    }

    for(i=97; i<=122; i++)
    {
        printf("%c --- %d -times\n",toupper(i),pole[i-97]);
    }


    // Sorting it here
    l= 25;
    do
    {
        max=0;
        for (x=0; x<=l; x++)
        {
            if (pole[x]>pole[max])
                max=x;
            else if (pole[x] == pole[max])
                if (abeceda[x] < abeceda[max])
                    max = x;
        }

        temp=pole[l];
        pole[l]=pole[max];
        pole[max]=temp;

        znak=abeceda[l];
        abeceda[l]=abeceda[max];
        abeceda[max]=znak;

        l--;
    }while (l!=0);

    for(y=25; y>-1; y--)
    {
        printf("%c  =  %d, ",toupper(abeceda[y]), pole[y]);
    }
    printf(" \n ");

    return 0;
}  

Исправленные проблемы и комментарии:

  • Как упоминалось в комментариях, вы пропустили ctype.h библиотека, которая предоставляет функции tolower и toupper - хотя я предполагаю, что это была опечатка.
  • Аналогично, как вы сказали, в инициализации abeceda была опечатка - она ​​должна иметь26 символов, а не 25, и закрывающая скобка должна была быть квадратной.Обратите внимание, что вы также можете написать char abeceda[] = {your list}, и компилятор сам определит размер массива.Ясно, что в этом случае формулирование этого явно представляется мне лучшей идеей, поскольку мы имеем дело с известным набором - алфавитом известного размера.Превращение ее в отдельную переменную и повторное использование этой переменной в циклах также кажется хорошим выбором.
  • Как писал @JonathanLeffler - используйте fgets вместо gets (и прочитайтесообщения из ссылки , которую он предоставил) - это реализовано вместе с заранее определенным максимальным размером буфера MAXBUF.
  • Вместо того, чтобы печатать буквы алфавита по порядку в последнем цикле, выхочу напечатать буквы в abeceda как отсортированные.
  • Наконец, как это было в OP, сортировка эффективно перепутала буквы с одинаковым количеством.Что он делает сейчас, так это то, что сортирует эти записи в алфавитном порядке букв, что, как я понял, было целью.
  • main() должен возвращать int вместо void (фактически вы возвращаетеint и это не скомпилируется на моей машине).
  • Некоторые имена переменных могли бы использовать улучшение, по крайней мере, на мой взгляд, в то время как znak ("знак") имеет некоторый смысл, pomm можетбыть просто заменено на temp.Также осторожно с однобуквенными переменными, такими как x и и yn, m ...) - лучше быть более многословным или, по крайней мере, придерживаться i, j, k, которые обычноиспользуется в петлях.n было бы более читабельным для меня, если бы это было что-то вроде nchar.
  • Используйте отступ для улучшения читабельности.Я бы также использовал меньше пробелов между частями кода.

Вывод слова Hello теперь будет выглядеть так:

L  =  2, E  =  1, H  =  1, O  =  1, A  =  0, B  =  0, C  =  0, D  =  0, F  =  0, G  =  0, I  =  0, J  =  0, K  =  0, M  =  0, N  =  0, P  =  0, Q  =  0, R  =  0, S  =  0, T  =  0, U  =  0, V  =  0, W  =  0, X  =  0, Y  =  0, Z  =  0,

Если вы хотите избавиться отпоследнюю запятую вы также можете сделать:

for(y=25; y>0; y--)
{
    printf("%c  =  %d, ",toupper(abeceda[y]), pole[y]);
}
printf("%c  =  %d ",toupper(abeceda[y]), pole[y]);
printf(" \n ");

Стоит отметить, что обычно вы хотите использовать более модульную конструкцию.В этом случае, по крайней мере, функция для сортировки, а не прямой ввод всего в main.Когда вы прогрессируете в учебе, я рекомендую начать писать функции, чем раньше, тем лучше.Они улучшают читаемость программ и облегчают отладку.

0 голосов
/ 04 октября 2018

Когда вы сортируете свой массив, вы теряете порядок букв.

Есть несколько способов исправить это, однако, вероятно, самый простой - это превратить полюс массива в двумерный массив..

Поэтому измените объявление полюса на:

int pole[26][2] = {0,0};

И затем добавьте цикл, чтобы установить вторую строку равной соответствующей букве в алфавите.

for (i = 0; i < 26; i++) {
  pole[i][1] = i;
}

Это должно сделать массив, который выглядит как

0, 0, 0, 0, ..., 0 <--- Эта строка является вхождениями (например, 10 появлений буквы A) </p>

0, 1, 2, 3, ..., 25 <--- Эта строка представляет значение (например, 0 = A, 1 = B, 2 = C) </p>

Теперь вы можете изменить свой видтакже отсортировать второй столбец.

do {
  max = 0;
  for (x = 0; x <= l; x++) {
    if (pole[x][0] > pole[max][0])
      max = x;

  }
  int tempNum = pole[l][0];     
  int tempLetter = pole[l][1];

  pole[l][0] = pole[max][0];
  pole[l][1] = pole[max][1];

  pole[max][0] = tempNum;
  pole[max][1] = tempLetter;
  l--;
} while (l != 0);

Это отсортирует ваш массив, и в итоге он будет выглядеть следующим образом:

15, 5, 1, 1, ..., 0

25, 2, 0, 1, ..., 12

(Z, C, A, B, ..., M) <- это второй ряд в виде букввместо чисел </p>

Вы можете получить эти значения, выполнив что-то вроде ...

for (i = 0; i < 26; i++) {
  printf("%c --- %d -times\n", pole[i][0], pole[i][1])
}

Это моя лучшая попытка объяснить это вам, надеюсь, вы понимаете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...