LinuxForum.Fans
Тема

Вспоминая Си

Автор: ShooricG 4 сообщений 1720 просмотров
#280078

Всем привет! :)

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

И вот, по истечении этих более 5 лет, я обнаруживаю, что на работе бывает появляется немного свободного времени. Чтобы даром его не терять, решил вспомнить тот самый Си. В связи с чем купил книгу "Язык программирования С" (Б.Керниган, Д.Ритчи; 2-е издание, "Вильямс", 2012г.) и установил на рабочий комп в (к сожалению) виртуалку Debian Wheezy.
Начал читать книгу с интересом. И вот, на середине первой главы (1.6 Массивы) встал в ступор при выполнении упражнения.

Упражнение 1.13: Напишите программу для вывода гистограммы длин слов во входном потоке. Построить гистограмму с горизонтальными рядами довольно легко, а вот с вертикальными столбцами труднее.

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

В книге 1 глава называется "Вводный урок" - соответственно ни о каких двумерных массивах речи не идет. Возникает вопрос - как решить данную задачу, используя только одномерный массив?

P.S.: во вложении два варианта моих мучений - 1-ый с одномерным массивом, 2-ой с двумерным массивом. Но по условию нужно дорабатывать первый вариант!

P.P.S.: заранее благодарен за любые наставления и тычиния носом! :D

Показать
Вариант решения с одномерным массивом:
text
#include <stdio.h>
#include <stdlib.h>

#define IN 1 /* in word */ #define OUT 0 /* out of word */

/* diagram of input's symbols */

main() { int c, s, nw, i, j, state, max; int diagram[20], invertion[20];

system("clear");

printf("Enter text with some words\n\n");

state = OUT; s = nw = j = 0;

/* determine the number of words */

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

/* symbol is not from word */ if (c == ' ' || c == '\n' || c == '\t') state = OUT;

/* symbol is from word and ++word*/ else if (state == OUT) { state = IN; ++nw; }

/* number of symbols in a word */ if (state == IN) ++s;

/* if number of symbols in a word not equal 0 (more that 0) then j's element in array assign number of symbols in a word; after this for the next word number of symbols for a start is equal 0 and enlarge number array's element */ else if (s != 0) { diagram[j] = s; s = 0; ++j; } }

printf("\n");

/* horisontal diagram */

for (j = 0; j < nw; ++j) { for (s = 0; s < diagram[j]; ++s) printf("*"); printf("\n"); }

printf("\n");

/* determine the maximum lenght of the words */

for (j = 0; j < nw; ++j) if (max < diagram[j]) max = diagram[j];

/* inverting number of symbols to the vertical diagram with 1 and 0 */

for (s = 0; s < max; ++s) { invertion[s] = 0; for (j = 0; j < nw; ++j) { if (diagram[j] != 0) { invertion[s] = ((invertion[s])*10 + 1); diagram[j]--; } else if (diagram[j] == 0) invertion[s] = (invertion[s])*10; } }

printf("\n");

/* printing vertical diagram with '*' and ' ' */

for (s = 0; s < max; ++s) { for (j = 0; j < nw; ++j) { if ((invertion[s] / (10^(nw - j))) == 1) printf("*"); else if (((invertion[s] / (10^(nw - j))) % 10) == 1) printf("*"); else if ((invertion[s] / (10^(nw - j))) == 0) printf("."); else if (((invertion[s] / (10^(nw - j))) % 10) == 0) printf("."); } printf("\n"); }

}

Показать
Вариант решения с двумерным массивом:
text
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define IN 1 /* in the word */ #define OUT 0 /* out of the word */

/* diagram of input's symbols */

main()

{ int nw, i, j, state, max; char diagram[20][20];

system("clear");

printf("Enter text with some words\n\n");

state = OUT; nw = i = j = max = 0;

/* determine the number of words and write the words to array */

/* nw (i) - number of words (rows); j - number of columns; */

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

if (i == ' ' || i == '\n' || i == '\t') { state = OUT; j = 0; }

else if (state == OUT) { state = IN; ++nw; }

if (state == IN) { ++j; if (max < j) max = j; diagram[j-1][nw-1] = i; }

}

for (j = 0; j < max; ++j) { for (i = 0; i < nw; ++i) printf(" %c ", diagram[j][i]); printf("\n"); }

}

#280100

Что-то вроде (только идея построения диаграммы по готовым данным):

text

#include <stdio.h>

print_vd(int ncol, int* data) { int i, j, max; max=data[0]; for (i=1; i<ncol; i++) if (data[i]>max) max=data[i]; for (j=max; j>0; j--) { for (i=0; i<ncol; i++) printf(" %c", data[i]>=j?'*':' '); printf("\n"); } }

int main(void) { int testdata[] = {2, 3, 4, 5, 3, 7, 2}; print_vd(sizeof(testdata)/sizeof(testdata[0]), testdata); return 0; }

text

           *  
           *  
       *   *  
     * *   *  
   * * * * *  
 * * * * * * *
 * * * * * * *
#280115

bormant, спасибо!

Получилось примерно так:

Показать
Решение с одномерным массивом:
text

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

#define IN 1 /* in word */ #define OUT 0 /* out of word */

/* diagram of input's symbols */

main() { int c, s, nw, i, j, state, max; int diagram[20], invertion[20];

system("clear");

printf("Enter text with some words\n\n");

state = OUT; s = nw = j = 0;

/* determine the number of words */

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

/* symbol is not from word */ if (c == ' ' || c == '\n' || c == '\t') state = OUT;

/* symbol is from word and ++word*/ else if (state == OUT) { state = IN; ++nw; }

/* number of symbols in a word */ if (state == IN) ++s;

/* if number of symbols in a word not equal 0 (more that 0) then j's element in array assign number of symbols in a word; after this for the next word number of symbols for a start is equal 0 and enlarge number array's element */ else if (s != 0) { diagram[j] = s; s = 0; ++j; } }

printf("\n");

/* determine the maximum lenght of the words */

for (j = 0; j < nw; ++j) if (max < diagram[j]) max = diagram[j];

/* printing vertical diagram with '*' and ' ' */

for (s = max; s > 0; --s) { for (j = 0; j < nw; ++j) { putchar(diagram[j] >= s ? '*' : ' '); } putchar('\n'); }

}

Так же спасибо за помощь NickLion

#280119

Хотелось бы, чтобы эту тему не закрывали, т.к. наверняка в ходе прочтения книги еще наверняка возникнут вопросы, а однородные темы плодить не хочется! *OK*
Спасибо!

Войдите или зарегистрируйтесь, чтобы ответить.