O
O
Oleg Filimonenko2019-02-10 16:26:51
C++ / C#
Oleg Filimonenko, 2019-02-10 16:26:51

Kernighan, Ritchie: Exercise 1.13 Am I missing something?

Good afternoon!
Without water and dust, straight to the point:
Brian Kernighan and Dennis Ritchie, second edition, paragraph 1.6 (Arrays), at the end of two exercises, one of them, in fact, the question:

Exercise 1.13. Write a program that prints histograms of the lengths of input words. A histogram is easy to draw with horizontal bars. Drawing with vertical stripes is a more difficult task.

I took it without hesitation and after a minute I formulated the algorithm in my head: We read the character and if it is missing \ tabulation \ new_line, then we move the cursor to a new line, otherwise we print the character.
#include <stdio.h>

int main()
{
    int c;

    while ((c = getchar()) != EOF)
    {

        if(c == ' ' || c == '\t' || c == '\n')
        {
            putchar('\n');
            
            while ((c = getchar()) == ' ' || (c = getchar()) == '\t' || (c = getchar()) == '\n')
            {
                putchar('\r');  //Для тех случаев, когда стоит нескоько пробелов, табуляций или новых строк подряд
                                //(Чтобы гиаграммма не росла вериткально, короче говоря, и была без разрывов)
            }
        }
        putchar('-');
     }
}

5c602663834e3748967543.png
I checked it - it works, it builds a horizontal diagram. Actually: ???
Here, either the task is specially with a catch, so that it can be solved using arrays and a bunch of branching conditions, or I'm a damn genius (which is definitely not true, I checked). I got into Google and found the following solutions, from which, to put it mildly, questions are asked by themselves (like: why is it so cumbersome and illogical?)
Here is an example:
#include <stdio.h>
#include <conio.h>
 
int main()
{
    int word_leangth = 0;
    char c;
    int i;
 
    while((c = getchar()) != '\n')                 //читаем одну строку
    {
        if (c != ' ')                              //если символ не пробел
            word_leangth++;          //+1 буковка в слове
        else                                      //а вот если он пробел
        {
            for(i = 0; i < word_leangth; i++)    //печатаем длину слова палочками горизонтальными
                printf("_"); 
            printf("\n");          //переходим на след. строку
            word_leangth = 0; 
        }
    }
 
    for(i = 0; i < word_leangth; i++) //печатаем длину посл. слова
        printf("_");                  //просто оно не заканчивается пробелом, а зак. знаком конца строки
 
    printf("\nPress any kay to exit\n");
    getch();                            //это просто чтобы спокойно посмотреть результат и выйти по нажатию любой кнопки
 
    return 0;
}

Or even this:
#include <stdio.h>
 
#define invischar 0 // непечатаемый символ
#define vischar 1   // печатаемый символ
#define maxwords 10 // количество слов ограничим десятью
 
int main(){
 
    int i, biggest = 0, num = 0, prevch = vischar; // индексы, счетчики, флажки
    int ch;        // текущий символ
    int nword[maxwords]; // массив с кол-вом эл-тов maxwords
 
    for(i = 0; i < maxwords; ++i) // инициализация массива
        nword[i] = 0;       
    i = 0;                 
 
    while((ch = getchar()) != EOF){ // начало заполнения массива
        if(ch == '\t' || ch == ' ' || ch == '\n')
            prevch = invischar;
        else{
            if (nword[i] > 0 && prevch == invischar){ // пропустим первые непечатаемые
                ++i; // переход к следующему элементу
                ++num; // счетчик числа непустых элементов
            }
            prevch = vischar;
            ++nword[i];
            if(nword[i] > biggest)
                biggest = nword[i]; // наибольший элемент(ы) массива
        }
    } //конец заполнения массива
 
    printf("%s\n", "Words length histogramm");
    while(biggest > 0){
        for(i = 0; i <= num; ++i)
            if(nword[i] >= biggest)
                putchar('I');
            else
                putchar(' ');
        putchar('\n');
        --biggest;
    }
    return(0);
}

Did I misunderstand the task? Maybe the task is to train the use of arrays? Just as for me - the shorter, more readable and simpler the code, the better. In no case do I want to breed holivars about beautiful / practical codes, the question is different: am I moving in that direction?
How would you solve this problem, what would you apply and most importantly - why one way or another? It is possible without giving code examples, the most important thing is to explain the essence.
I will be glad for any answers and advice. Thanks in advance to all who respond, I really appreciate it.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Vladimir Dubrovin, 2019-02-11
@z3apa3a

The histogram of lengths shows the distribution of the number of encountered words from their length, i.e. you need to draw n stripes (from 1 to n where n is the maximum length of a word), each strip should have a number of divisions proportional to the number of words of a given length. Those. if there are twice as many 6-character words as 8-character words, then the 6-character word bar should be twice as long.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question