Как напечатать частоту символов в строке? - PullRequest
1 голос
/ 06 июля 2019

Предположим, что ввод

дерево

Следующий код показывает вывод t1r1e2e2. Как мне избежать печати e2 дважды?

int main() 
{
    char a[20];
    int count, j, i, k; //abcd
    gets(a);
    int p = strlen(a);

    for (j = 0; j < p; j++) {
        count = 0;
        for (k = 0; k < p; k++) {
            if (a[j] == a[k])
                break;
        }
        for (i = 0; i < p; i++) {
            if (a[j] == a[i]) {
                count++;
            }
        }
        printf("%c%d", a[j], count);
    }
}

Ответы [ 2 ]

0 голосов
/ 06 июля 2019

Вот еще один.Вы можете обработать столько данных, сколько пожелаете, просто вызвав функцию процесса.Функция init обнуляет счетчики.Он печатает также непечатаемые шестнадцатеричные числа символов '\x0a', например

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

static unsigned freqtable[256];

void init(void)
{
    memset(freqtable, 0, sizeof(freqtable));
}

unsigned *process(const unsigned char *buff, size_t size)
{
    while(size--)
    {
        freqtable[*buff++]++;
    }
    return freqtable;
}

void print(void)
{
    for(unsigned i = 0; i < 256; i++)
    {
        if(freqtable[i])
        {
            if(ispunct(i) || isalnum(i))
            {
                printf("%c%u", i, freqtable[i]);
            }
            else
            {
                printf("'\\x%02x%u", i, freqtable[i]);
            }
        }
    }
    printf("\n");
}

#define T1 "tree"

#define T2 "\r\nHello world \r\n\r\n"

int main()
{
    init();
    process(T1, strlen(T1));
    print();
    process(T2, strlen(T2));
    print();
    init();
    process(T2, strlen(T2));
    print();    

    return 0;
}
0 голосов
/ 06 июля 2019

есть некоторые проблемы в вашем коде

  • не использовать получает , он устарел, и если вы вводите слишком длинный ввод, вы записываете из получающей строки снеопределенное поведение
  • ваш цикл с k бесполезен
  • вы используете int , но правильный тип size_t, потому что int может быть недостаточно большим

Один из способов - изменить строку, предположив, что вы не хотите считать строки, а также изменить способ печати результата, чтобы сделать его более читабельным:

#include <stdio.h>

int main() 
{
  char a[20];

  if (fgets(a, sizeof(a), stdin) != NULL) {
    for (size_t j = 0; a[j] != 0; ++j) {
      char c = a[j];

      if (c != '\n') {
        size_t count = 1;

        for (size_t i = j + 1; a[i] != 0; i++) {
          if (a[j] == a[i]) {
            count += 1;
            a[i] = '\n'; /* to not count it again */
          }
        }

        printf("%c : %zu\n", a[j], count);
      }
    }
  }

  return 0;
}

Компиляция и выполнение:

pi@raspberrypi:/tmp $ g++ -pedantic -Wall -Wextra c.c
pi@raspberrypi:/tmp $ ./a.out
tree
t : 1
r : 1
e : 2
pi@raspberrypi:/tmp $ ./a.outpi@
output input
o : 1
u : 3
t : 3
p : 2
  : 1
i : 1
n : 1
pi@raspberrypi:/tmp $ 

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

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