Распечатать гистограмму, основанную на длине слова (C) - PullRequest
15 голосов
/ 21 октября 2010

Это упражнение K & R (1-13) ...

"Напишите программу для печати гистограммы длины слов в его входе. Гистограмму легко нарисовать с помощью бары горизонтальные; вертикаль ориентация более сложная. "

Раздел посвящен массивам, и, если честно, я не уверен, что полностью это понял. Все до этого момента было довольно легко понять, это было не так.

В любом случае я сначала пытаюсь сделать гистограмму с горизонтальными полосами. Как только я получу это, я попробую вертикальный, но сейчас я даже не уверен, с чего начать с простой версии. (Я спал на нем, проснулся, и все еще не мог получить это.)

Я нарисовал пример того, что программа выдаст:

----------------------------------------------------------------
001|XX
002|XXXX
003|X
004|XXXXXXXXXX
005|XXXXXXXXXXXXXXXXXXXXXXXXX
006|XXXX
007|X
008|
009|XXXXXXXXX
010|XXX
>10|XXXX
----------------------------------------------------------------

И попытался разбить его (программу) на разделы. Вот что я придумал:

  1. ПЕЧАТЬ ВЕРХНЕЙ ГРАНИЦЫ
  2. ПЕЧАТЬ КАТЕГОРИИ, ПЕЧАТЬ X КАЖДОЕ ВРЕМЯ СОСТОЯНИЕ ПРАВДА, ПЕЧАТЬ НОВОЙ ЛИНИИ, REPEAT.
  3. ПЕЧАТЬ НИЖНЕЙ ГРАНИЦЫ

Но чем больше я думаю об этом, тем меньше думаю, что так оно и будет работать (потому что getchar() проходит по одному символу за раз, и он не сможет вернуться наверх, чтобы поставить X в правильном категория.) Или ...

... Я просто смущен тем, как бы я решил эту проблему. Вот, насколько я смог получить код мудрый:

#include <stdio.h>

#define MAXWORDLENGTH 10

// print a histogram of the length of words in input. horizontal bar version

int main(void)
{
  int c;
  while ((c = getchar()) != EOF) {

  }

  return 0;
}

Может ли кто-нибудь помочь мне просветить? Не обязательно с кодом, может быть, просто с псевдокодом, или с некоторыми «мудрыми словами» о том, что мне нужно делать, или думать, или что-то еще. Это был действительно большой камень в дороге, и я хотел бы обойти его: /.

(я вернусь через 30 минут)

Ответы [ 15 ]

0 голосов
/ 01 декабря 2018

На вопрос уже дан ответ с использованием массива. Код ниже печатает горизонтальную гистограмму без использования массива. При свободном определении слова это любая последовательность символов, которая не содержит пробелов, табуляции или новой строки.

#include<stdio.h>
#define BLANK ' '
#define TAB '\t'
#define NEWLINE '\n'
#define RESET 0

void main()
{
    int c, num_char = 0, num_line = 0;
    while((c = getchar()) != EOF)
    {
        if(c == BLANK || c == TAB || c == NEWLINE)
        {
            printf("%d.: ", num_line);
            for(int i = 0; i < num_char; ++i)
                printf(" *");
            putchar(NEWLINE);
            ++num_line;
            do
            {
                c = getchar();
            }while(c == BLANK || c == TAB || c == NEWLINE);
            num_char = RESET;
        }
        ++num_char;
    }
}
0 голосов
/ 01 сентября 2015
// Histogram to print the length of words in its input
#include <stdio.h>
main()
{
    int wordcount[10],c,token=0;
    int word=0, count =0;
    for (int i=0; i<10; i++)
    {
        wordcount[i]=0;
    }

    while((c=getchar())!=EOF)
    {
     if(c== ' ' || c == '\n' || c== '\t')
     {
         // add the length of word in the appropriate array number 
         switch(word)
         {
            case 1:
            ++wordcount[0];break;
            case 2:
            ++wordcount[1];break;
            case 3:
            ++wordcount[2];break;
            case 4:
            ++wordcount[3];break;
            case 5:
            ++wordcount[4];break;
            case 6:
            ++wordcount[5];break;
            case 7:
            ++wordcount[6];break;
            case 8:
            ++wordcount[7];break;
            case 9:
            ++wordcount[8];break;
            case 10:
            ++wordcount[9];break;
         }
         word =0;
     }
     else if (c != ' ' || c != '\n' || c!= '\t')
     {
         word++;
     }

}
    for (int j=0; j<10; j++)
    {
        if(wordcount[j]==0)
        {
            printf("- ");
        }
        for (int k=0;k<wordcount[j];k++)
        printf("X", wordcount[j]);
        printf("\n");
    }


}
0 голосов
/ 17 апреля 2014

Хотя упражнение основано на массивах, я попытался написать его, используя базовый цикл while и оператор if. Я не очень хорошо разбираюсь с массивами, так что подумал попробовать это. Я не проверял его на наличие ошибок, но, похоже, он работает нормально для большинства входных данных.

    #include<stdio.h>   
    main() {
    long int c;         

    while((c=getchar())!=EOF) { 
        if(c!=' '&&c!='\n'&&c!='\t') {
            putchar("*");
        }

        if(c==' '||c=='\n'||c=='\t') {   
            putchar('\n');   
        } 

    }
    return 0;
    }

Обратите внимание, что это очень простой фрагмент кода для горизонтальной печати, просто для базового понимания структуры.

0 голосов
/ 16 сентября 2012

Вертикальная гистограмма может быть напечатана по одной строке за раз, просматривая массив длин слов и уменьшая длину слов на каждой итерации.Знак # печатается, если длина слова все еще выше нуля, а пробел печатается, когда он достигает 0. Новая строка печатается после каждой итерации.

Если length [i] содержит количество символов для слова i, а wordn - это общее количество слов, тогда вертикальная гистограмма будет напечатана следующим:

#define YES 1
#define NO 0


 more_lines = YES;
 while (more_lines)
 {
  more_lines = NO; 
  for (i = 1; i <= wordn; ++i)
          {
        if (lengths[i] > 0 ) 
                {
                  more_lines = YES;
                  printf("#\t");
                  --lengths[i];
                }
        else 
                 printf(" \t"); 
      }
  putchar('\n');
 }

Полный код приведен ниже:

#include<stdio.h>
/* Prints a histogram of the lenghts of words */

#define MAX_WORDS 100
#define IN 1
#define OUT 0

#define YES 1
#define NO 0

main()
{
 int c, length, wordn, i, j, state, more_lines, lengths[MAX_WORDS];
 wordn = length = 0;
 state = OUT;
 for (i = 0; i < MAX_WORDS; ++i) lengths[i] = 0;

 while ((c = getchar()) != EOF && wordn < MAX_WORDS)
 {
    if (c == ' ' || c == '\t' || c == '\n')
        state = OUT;

    else if (wordn == 0) 
        {
         state = IN;
         ++wordn;
         ++length;
        }

    else if (state == IN)
         ++length;

    else if (state == OUT)
        {
         lengths[wordn] = length;
         ++wordn;
         length = 1;
         state = IN;
        }
 }    

 lengths[wordn] = length;

/* Print histogram header */
  for (i = 1; i <= wordn; ++i)    
printf ("%d\t", i);
  putchar('\n');

 more_lines = YES;
 while (more_lines)
 {
  more_lines = NO; 
  for (i = 1; i <= wordn; ++i)
      {
    if (lengths[i] > 0 ) 
        {
          more_lines = YES;
          printf("#\t");
          --lengths[i];
        }
    else 
         printf(" \t"); 
      }
  putchar('\n');
 }
}
0 голосов
/ 21 октября 2010

Вы должны разделить ваши 2 задачи по функциям, например:

void gethist(char *s, int *hist, int len)
{ /* words here breaks on spaces (' ') */
  char *t;
  for( t=strtok(s," ");t;t=strtok(0," ") )
    if(*t)
      hist[ strlen(t)>len-1?len-1:strlen(t)-1 ]++;
}

void outhist(int *hist, int len)
{
  int i;
  for( i=1; i<=len; ++i )
  {
    char *s = calloc(1,5+hist[i-1]);
    sprintf(s,"%03d|", i);
    memset( s+4, 'X', hist[i-1]);
    puts(s);
    free(s);
  }
}

, тогда все будет просто:

int main(void)
{
  int c, hist[11] = {};

  char *s = calloc(1,1);
  while ((c = getchar()) != EOF) {
    s = realloc( s, 2+strlen(s) );
    s[ strlen(s)+1 ] = 0;
    s[ strlen(s) ] = c;
  }

  gethist(s,hist,11); free(s);
  outhist(hist,11);

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