Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 04.11.2011, 23:23   #11
SlivTime
Новичок
Джуниор
 
Регистрация: 04.11.2011
Сообщений: 2
По умолчанию

На скорую руку написал программу к следующему упражнению. С кириллицей заморачиваться не стал.

1.14. Напишите программу для вывода гистограммы частот, с которыми
встречаются во входном потоке различные символы.

Код:
#include <stdio.h>

/* Вывод гистограммы частот, с которыми встречаются во входном потоке различные символы */
main()
{
	int i, j, c, MaxLenght, MaxValue;
	int LettersFreq[128];	// Для простоты ограничимся латинскими символами

	MaxLenght = MaxValue = 0;
	for ( i = 0; i < 128; ++i) 
		LettersFreq[i] = 0;

	//Заполнение массива
	while ((c = getchar()) != EOF) {  			 
		++LettersFreq[c];
	}

	//Вычисление границ гистограммы
	for ( i = 0; i < 128; ++i) {
		if ( MaxValue < LettersFreq[i] )
			MaxValue = LettersFreq[i];
		if ( LettersFreq[i] != 0 )
			++MaxLenght;
	}

	//Вывод результата
	printf("\n");
	for ( i = MaxValue; i > -1; --i ) {
		if ( i > 0) 
			printf("%2d ", i);
		else if ( i == 0 ) 
			printf("   ");
		for ( j = 31; j < 128; j++ ) {	//Отбросим непечатные символы
			if ( i > LettersFreq[j] && LettersFreq[j] != 0 )
				putchar(' '), putchar(' '), putchar(' ');
			else if ( i == 0 && LettersFreq[j] != 0 )
				if ( j == ' ' )
					printf("' '");
				else
					printf("%2c ", j);
			else if ( LettersFreq[j] != 0 )
				putchar(177), putchar(177), putchar(177);
		}
		printf("\n");
	}
}
Отправляем на вход "London is the capital of Great Britain!", получаем:

Код:

 6 ±±±                                                      
 5 ±±±                                                      
 4 ±±±            ±±±               ±±±                  ±±±
 3 ±±±            ±±±               ±±±   ±±±±±±         ±±±
 2 ±±±            ±±±      ±±±      ±±±   ±±±±±±   ±±±   ±±±
 1 ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
   ' ' !  B  G  L  a  c  d  e  f  h  i  l  n  o  p  r  s  t
Вроде как работает правильно, но слишком уж перегружен код вывода. Или это нормально?
SlivTime вне форума Ответить с цитированием
Старый 23.12.2011, 07:03   #12
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

SlivTime, 1.13, 1.14 - отличные решения. На каком упражнении сейчас?
8Observer8 вне форума Ответить с цитированием
Старый 08.03.2012, 12:40   #13
pu6ka
 
Регистрация: 08.03.2012
Сообщений: 4
По умолчанию

Цитата:
Сообщение от Roof Посмотреть сообщение
2 8Observer8

Это нехороший подход. Лучше выполнять самому упражнения. Они на это и рассчитаны - самостоятельная работа. Получаешь некоторый опыт самостоятельного мышления, а не просто осознание прочитанного. Этот опыт ценен.
Полностью согласен. Есть "Книга ответов" Тондо, где даются решения упражнений Кернигана и Ритчи. Но я стараюсь, прежде самостоятельно решить, а потом смотрю как решали авторы данного издания. Например упражнения 1.9, которым открыт этот пост они решили используя символическую константу NONBLANK. Хотя у K&R она не описывается, по крайне мере до этого упражнения:
Код:
#include <stdio.h>
#define NONBLANK 'a'
/* заменить строку пробелов единственным*/
main()
{
	int c, lastc;
	lastc = NONBLANK;
	while ((c = getchar()) != EOF) {
		if (c != ' ')
			putchar(c);
		if (c == ' ')
			if (lastc != ' ')
				putchar (c);
		lastc = c;
	}
}
Я два часа перед этим корпел над упражнением, вот что получилось:
Код:
#include <stdio.h>
// замена нескольких подряд стоящих пробелов на один
main()
{
 int c, ns;
 while ((c=getchar()) != EOF ) {
	if (c != ' ') ns=0;     	// если след.символ не пробел, обнулим счетчик
 	if (c == ' ') ++ns;			// если след.символ пробел, увеличим счетчик на единицу
 	if (ns<=1) putchar (c);		// если счетчик до единицы, печатаем
 }
}
Может, конечно, не все возможные варианты учел, буду признателен если кто укажет, в каких случаях программа будет работать некорректно. Я вторую неделю только как начал изучать K&R. Но обе программы на несколько пробелов подряд, вперемежку со словами у меня реагируют одинаково.
pu6ka вне форума Ответить с цитированием
Старый 08.03.2012, 18:43   #14
EUGY
Форумчанин
 
Аватар для EUGY
 
Регистрация: 11.07.2010
Сообщений: 914
По умолчанию

Цитата:
Код:
include <stdio.h>
// замена нескольких подряд стоящих пробелов на один
main()
{
 int c, ns;
 while ((c=getchar()) != EOF ) {
	if (c != ' ') ns=0;     	// если след.символ не пробел, обнулим счетчик
 	if (c == ' ') ++ns;			// если след.символ пробел, увеличим счетчик на единицу
 	if (ns<=1) putchar (c);		// если счетчик до единицы, печатаем
 }
}
Цитата:
буду признателен если кто укажет, в каких случаях программа будет работать некорректно
Разве что попридираться
Работать некорректно будет сразу, достаточно пробелу быть первым символом.
Ну, и, когда количество пробелов идущих подряд превысит лимит для int.
EUGY вне форума Ответить с цитированием
Старый 09.03.2012, 01:29   #15
8Observer8
Старожил
 
Аватар для 8Observer8
 
Регистрация: 02.01.2011
Сообщений: 3,323
По умолчанию

Вы вовремя тему подняли, так как я сейчас перечитываю книгу в третий раз, но уже на английском. На всякий случай прикрепил книгу к данному сообщению. Это HTML книга. Удобно искать нужные параграфы, а главное быстро. Пока прочитал 1 главу. Упражнения делал далеко не все.

Самый первый вариант решения упражнения 1-9 (ссылка, это код из самого первого моего сообщения) содержит ошибку в алгоритме.

После запуска программы я ввёл:
Код:
23 23
Получил:
Код:
23 2 3
Суть ошибки:
Не учитывал, что число пробелов может быть единица.

Я ещё, тогда задание неправильно понял (наверное). Программа должна считывать входной поток (состоящий из строк), а не одну строку.

То есть я ввожу:
Код:
123  123    123
123 123   123
123    123  123
Далее, ввожу символ конца файла (для Windows Ctrl+Z и Enter)

Получаю:
Код:
123 123 123
123 123 123
123 123 123
А непросто, ввожу строку, нажимаю Enter, получаю результат:

Пример.
Ввожу:
Код:
123   123
Нажимаю Enter.

Получаю:
Код:
123 123
Поэтому, в будущем, надо сделать для потока из строк.

По рекомендации |{ot'a из второго сообщения данной темы, имеем:
Код:
#include <stdio.h>
#include <locale.h>

/* замена нескольких пробелов одним */
int main ()
{
    int c;
    // previousIsSpace - предыдущий символ - пробел? 0 - нет; 1 - да
    register int previousIsSpace = 0;

    setlocale(LC_ALL, "Russian");
    printf("Замена нескольких пробелов одним.\n");

    while ((c = getchar()) != EOF) {
        if (c != ' ') {
            putchar(c);
            previousIsSpace = 0;//пусть лучше этот код повторяется
        
        } else {
           if (!previousIsSpace) {
               putchar(' ');
               previousIsSpace = 1;
           }
         
        }
    }

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

В виде (авторов будем указывать, совместное выполнение или одиночное):
Промежуточный итог:
Упражнение 1-9. --> http://codepad.org/KOOSg5Y7
Упражнение 1-10. -->
Упражнение 1-11. -->

P.S. По мере того, как у вас будет появляться код или наработки, то выкладывайте их сюда. Надо тему "добивать".
P.S.S. Через пару дней я внимательнее посмотрю ваш код и пересмотрю предыдущие замечания наших коллег. И мы будем искать оптимальные решения, учитывающие, что мы "знаем" до данного упражнения.
P.S.S.S. Книгу с решениями, если можно, приложите к сообщению. Будем подглядывать после разборов кода.
Вложения
Тип файла: rar B. Kernighan, D. Ritchie - The C Programming Language.rar (205.8 Кб, 16 просмотров)

Последний раз редактировалось 8Observer8; 09.03.2012 в 01:34.
8Observer8 вне форума Ответить с цитированием
Старый 10.03.2012, 00:30   #16
pu6ka
 
Регистрация: 08.03.2012
Сообщений: 4
По умолчанию

Цитата:
Сообщение от EUGY Посмотреть сообщение
Разве что попридираться
Работать некорректно будет сразу, достаточно пробелу быть первым символом.
Да, точно. Я думал, объявленная переменная инициализируется нулем автоматически. По аналогии с другим языком, который учил. Спасибо, что подметили.
Так вот работает и с первым пробелом. Упражнение 1.9 :
Код:
#include <stdio.h>
// замена нескольких подряд стоящих пробелов на один
main()
{
 int c, ns = 0;
 while ((c=getchar()) != EOF ) {
	if (c != ' ') ns=0;     	// если след.символ не пробел, обнулим счетчик
 	if (c == ' ') ++ns;			// если след.символ пробел, увеличим счетчик на единицу
 	if (ns<=1) putchar (c);		// если счетчик до единицы, печатаем
 }
}
pu6ka вне форума Ответить с цитированием
Старый 10.03.2012, 01:09   #17
pu6ka
 
Регистрация: 08.03.2012
Сообщений: 4
По умолчанию

Ссылка с книгой ответов Тондо и Гимпела в разделе с литературой

Последний раз редактировалось pu6ka; 10.03.2012 в 01:27. Причина: уточнение
pu6ka вне форума Ответить с цитированием
Старый 17.03.2012, 19:47   #18
shtaler
Новичок
Джуниор
 
Регистрация: 17.03.2012
Сообщений: 2
По умолчанию

Добрый вечер, уважаемые
Тоже читаю Кернигана и Ричи и выполняю упражнения. Возник вопрос по упражнению 1.9, запуталась немножко в ветвлениях, гугл отправил к вам, почитала эту ветку и пришла к выводу, что я похоже несколько иначе понимаю задание. Моё видение вопроса:
Я ввожу:

123 456
пробел, пробел
абв где
231
пробел
жзи 123

в задании говорится "..СТРОКИ, состоящей из одного или нескольких пробелов", поэтому на мой взгляд программа должна преобразовать это в:

123 456 абв где
231 жзи 123

Поправьте меня, пожалуйста, если я не права и только усложняю себе задачу)) потому что я тут пытаюсь еще кроме пробелов отслеживать \n и убирать лишние переходы на новую строку, если она состоит только из пробелов %)

Последний раз редактировалось shtaler; 17.03.2012 в 19:55.
shtaler вне форума Ответить с цитированием
Старый 18.03.2012, 23:32   #19
pu6ka
 
Регистрация: 08.03.2012
Сообщений: 4
По умолчанию

Цитата:
Сообщение от shtaler Посмотреть сообщение
в задании говорится "..СТРОКИ, состоящей из одного или нескольких пробелов", поэтому на мой взгляд программа должна преобразовать это в:
Заглянул в свою книгу K&R, написано тоже как и у Вас "СТРОКИ". Но я занимаюсь больше по скачанному варианту, там другой переводчик, и вот как у него звучит упражнение 1.9 "Напишите программу, копирующую символы ввода в выходной поток и заменяющую стоящие подряд пробелы на один пробел."
Уже самому интересно стало. Поднял оригинальное описание (вместе с решением можно посмотреть здесь:http://clc-wiki.net/wiki/K%26R2_solu...r_1:Exercise_9): "Write a program to copy its input to its output, replacing each string of one or more blanks by a single blank." После запятой "заменяя каждый string из одного или более пробелов на одиночный пробел". На translate.ru первое значение слова string переводится как последовательность. Ну и решение задачи показывает, что все-таки речь идет о замене подряд стоящих пробелов.
pu6ka вне форума Ответить с цитированием
Старый 19.03.2012, 16:18   #20
shtaler
Новичок
Джуниор
 
Регистрация: 17.03.2012
Сообщений: 2
По умолчанию

Мммм, понятно, спасибо большое за ответ!
Я просто упёрлась в "..один или более..". Подумала, что смысла заменять один пробел на один нет)) Я бы написала "два или более" тогда)))
А возможно решить задачу, которую я ставлю, но обладая только знаниями, которые мы приобрели до задания 1.9? Ну так, ради интереса)) getchar () я так понимаю обрабатывает только одну строку ведь? Алгоритм я придумала, вполне себе работоспособный имхо, но при запуске программы обработка введенных данных начинается по нажатию Enter а не ctrl+z + Enter, то есть ввести многострочный текст у меня не выходит Не знаю понятно ли я изъясняюсь и может сама чего-то недопонимаю, но не кидайте тапками, пожалуйста, мне очень хочется разобраться, правда))
shtaler вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Упражнения c# veter48 Помощь студентам 0 12.07.2011 18:53
[Си] Упражнения Fobo5 Помощь студентам 1 02.02.2011 21:22
(С) Простое упражнение из Кернигана, Ричи. Пробелы Матвейка Помощь студентам 1 07.06.2009 12:37
Упражнения делфи MAKEDON Свободное общение 1 26.08.2008 02:31