Распечатать гистограмму, основанную на длине слова (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 ]

7 голосов
/ 21 октября 2010

Мне понравился псевдокод!Есть хорошие мысли, но вы все еще не упорядочиваете свою программу правильно.

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

Поэтому вы должны думать, что ваша программа состоит из двух частей (и вы сделаете этот видделения практически в каждой написанной вами программе): во-первых, часть, которая будет производить вычисления;а затем часть, которая выведет их в определенном формате (гистограмма).

Этот совет должен помочь вам начать!Если вам нужна дополнительная помощь, прокомментируйте ниже.

3 голосов
/ 21 октября 2010

Я предлагаю вам упростить задачу, решив ее для случая одного слова в строке, чтобы вы могли использовать fgets.Вот как «съесть» слишком длинные строки .

Тогда, как часто, центральная структура данных является ключом к решению проблемы.Нужная вам структура данных - это массив, используемый в качестве таблицы частот:

int freq[11];

В freq[1] сохраните количество слов / строк длины 1, в freq[2] - слов длины 2 и т. Д.и в freq[0] те длиной> 10.Вам не нужно хранить слова, так как остальная часть программы нуждается только в их длине.Написание гистограммы теперь должно быть простым.

Надеюсь, это не слишком спойлер.

2 голосов
/ 25 декабря 2013
#include<stdio.h>
#define RESET 0
#define ON 1

main()
{
  int i,wnum=0,c,wc[50];
  int count=0,state;
  state=RESET;
  for(i=0;i<50;++i)
    wc[i]=0;
  /*Populating the array with character counts of the typed words*/
  while((c=getchar())!=EOF)
    {
      if(c=='\n'||c=='\t'||c==' '||c=='"')
    {
      if(state!=RESET)
        state=RESET;
    }
      else if((c>=65&&c<=90)||(c>=97&&c<=122))
    {
      if(state==RESET)
        {
          count=RESET;
          ++wnum;
          state=ON;
        }
      ++count;
      wc[wnum-1]=count;
    }
    }
  c=RESET;

  /*Finding the character count of the longest word*/
  for(i=0;i<wnum;++i)
    {
      if(c<wc[i])
    c=wc[i];
    }

  /*Printing the Histogram Finally*/ 
 for(i=c;i>0;--i)
    {
      for(count=0;count<wnum;++count)
    {
      if(wc[count]-i<0)
        printf("  ");
      else printf("x ");
    }
      printf("\n");
    }
}

ВЕРТИКАЛЬНАЯ ОРИЕНТАЦИЯ: Использование только инструментов, которые мы изучили до сих пор в книге. И вы можете изменить размер массива, wc [50]. Я сохранил код в течение 50 слов. Горизонтальная ориентация должна быть довольно простой. Я не пробовал это все же.

2 голосов
/ 15 сентября 2012

Приведенный ниже код печатает горизонтальную гистограмму, используя только базовый инструментарий, предоставленный в книге:

#include<stdio.h>

/* Prints a horizontal histogram of the lengths of words */

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

main()
{
 int c, length, wordn, i, j, state, 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;

 for (i = 1; i <= wordn; ++i)
    {
     printf("%3d: ",i);
     for (j = 0; j < lengths[i]; j++)
        putchar('-');
    putchar('\n');
    }
}
1 голос
/ 02 октября 2017
//This is for horizontal histogram.
//It works for any number of lines of words where total words <= MAX
#include <stdio.h>
#define MAX 100 //Change MAX to any value.But dont give words more than MAX.

void main()
{
    int w, nwords[MAX] = {0}, i = 0;   //nwords is an array for storing length of each word.Length of all words initialized to 0.

    while ((w = getchar()) != EOF)
    {
        if (w == ' ' || w == '\t' || w == '\n')
            ++i;            //if space or tab or newline is encountered, then index of array is advanced indicating new word
        else
            ++nwords[i];        //increment the count of number of characters in each word
    }       //After this step,we will have array with each word length.

    for (i = 0; i < MAX; i++)   //iterating through array
    {
        printf("\n");
        for (; nwords[i] > 0; nwords[i]--)  
            printf("$");        //if length of word > 0 , print $ and decrement the length.This is in loop.
        if (nwords[i+1] == 0)   //as MAX is 100, to avoid printing blank new lines in histogram,we check the length of next word.
            break;              //If it is 0, then break the loop
        printf("\n");   //After each word bar in histogram, new line.
    }
    printf("\n");
} //main
1 голос
/ 21 октября 2010

Я свяжу ответ ниже, но поскольку вы спрашивали подробности, ключ, кажется, был следующим:

Использовать массив длин, т.е. иметь массив с каждым элементом, инициализированным в ноль, предполагая, что длина слова MAX равна приблизительно 30...

* имеют флаг в слове и увеличивают счетчик каждый раз, когда пробел НЕ встречается

* после того, как из флага слова установлено значение "out" и соответствующее словоЭлемент индекса длины в массиве увеличивается, т. е. если счетчик длины слова равен w_ctr, используйте

array[w_ctr]++

*. Используйте массив в качестве таблицы ссылок для каждой строки в цикле, чтобы вывести каждую строку в гистограмме, чтобы выиспользуйте массив и теперь сможете определить, нужно ли вставлять 'X' в гистограмму или нет

РЕДАКТИРОВАТЬ: извините, я не правильно прочитал вопрос, но идея для вертикальных гистограмм проще ито же самое можно использовать.

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

for(ctr=0;ctr<array[current_wordlength];ctr++)
     printf('X');    

Конец


оригинал здесь http://users.powernet.co.uk/eton/kandr2/krx113.html

CLC-wiki - это также место, смотрите подробности в комментариях.

1 голос
/ 21 октября 2010

Для гистограммы длин слов вам нужно знать длину слов.

  • Как вы определяете слово?
  • Как вы можете измерить длину слова?слово?Можете ли вы делать это по одному символу за раз, когда читаете поток, или вам следует буферизовать ввод, используя strtok или что-то подобное?

Вам нужно будет накапливать данные о том, сколько вкаждая длина встречается.

  • Как вы будете хранить эти данные?

Вам нужно будет вывести результаты в приятной форме.Это неудобно, но не сложно.

0 голосов
/ 12 января 2019

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

#define MAXWORDS 20
#define MAXLENGTH 10

int c, nlength = 0, i, nword = 0, j;
    int length_words[20]= {0};

    while((c = getchar()) != EOF && nword <= MAXWORDS)
    {
        if(c != ' ' && c != '\t' && c != '\n')
            ++nlength;
        else
        {
            if(nlength != 0){
                length_words[nword] = nlength;
                ++nword;
               /* for(i = 0; i < nlength; i++)
                printf("O");
                printf("\n");*/
                printf("Word number: %d has length: %d\n", nword - 1, nlength);
            }
            nlength = 0;
        }
    }
    // Displaying the Histogram
    for(i = MAXLENGTH; i > 0; i--)
    {
        for(j = 0; j < nword; j++)
        {
            if(i > length_words[j])
                printf("   ");
            else
                printf(" O ");
        }
        printf("\n");
    }

Не стесняйтесь запустить это и сообщите мне в случае любого несоответствия или лазеек!

0 голосов
/ 17 декабря 2018
#include <stdio.h>
#include <string.h>

int main()
{
    //hold length of string
    unsigned long length;
    // Holds the name input by user upto 50 characters
    char name[50];
    //iterator for generating dash for bar chart
    int i = 0;
    //iterator for generating dash for bar chart
    int j = 0;
    //take user name input
    printf("input your name [without spaces and < 50 characters] : ");
    scanf("%s", &name[0]);
    //find the length of string
    length = strlen(name);
    printf("length of your name is %lu \n", length);
    //generate dashes for bar chart
    while (i < length)
    {
        printf("--");
        ++i;
    }
    printf("| \n");
    // fill the bar chart with []
    while (j < length)
    {
        printf("[]");
        ++j;
    }
    printf("| \n");
    //generate dashes for bar chart
    while (length > 0)
    {
        printf("--");
        --length;
    }
    printf("| \n");
}

введите ваше имя [без пробелов и <50 символов]: ThisIsAtestRun </p>

длина вашего имени 14

----------------------------|
[][][][][][][][][][][][][][]|
----------------------------|
0 голосов
/ 07 декабря 2018

Вот пример простой вертикальной гистограммы

#include <stdio.h>

int main()
{
    int c, i, j, max;
    int ndigit[10];

    for (i = 0; i < 10; i++)
        ndigit[i] = 0;

    while ((c = getchar()) != EOF)
        if (c >= '0' && c <= '9')
            ++ndigit[c-'0'];

    max = ndigit[0];
    for (i = 1; i < 10; ++i)        /* for Y-axis */
        if (max < ndigit[i])
            max = ndigit[i];

    printf("--------------------------------------------------\n");
    for (i = max; i > 0; --i) {
        printf("%.3d|", i);
        for (j = 0; j < 10; ++j)
            (ndigit[j] >= i) ? printf(" X ") : printf("   ");
        printf("\n");
    }
    printf("   ");
    for (i = 0; i < 10; ++i)        /* for X-axis */
        printf("%3d", i);
    printf("\n--------------------------------------------------\n");
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...