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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.07.2017, 17:27   #1
goto ∞
Форумчанин
 
Аватар для goto ∞
 
Регистрация: 21.12.2010
Сообщений: 155
По умолчанию Задачка из К&Р 2

Вывести частоту появления вводимых символов.
То есть если вводится поток "aabbc 12344" узнать какие символы сколько раз появляются. Тут например будет символ "a" -2 раза "b" тоже два раза и "4" по два раза остальные по одному разу появляются
Я сделал с помощью двух массивов. В первом массиве записываем весь поток потом удаляем повторяющиеся элементы и в то же время считаем количество повторений и сразу записываем во второй массив.
Правильно ли так делать или возможно сделать по легче.
Код:
#include <stdio.h>
#define MAX 100 /* Максимальное количество символов в потоке*/

int main(){
	int count;  /*Количество введенных символов*/
	int c,i,j,k;
	int ms[MAX];/*Для хранения симовлов*/
	int mc[MAX];/*Массив частот символ*/
	
	count = 0;
	
	for(i = 0; i < MAX; ++i){
	ms[i] = mc[i] = 0;
	}
	
	while( (c = getchar()) != EOF){
		if ( c != ' ' ){
			ms[count] = c;
			count++;
		}
	}

	i = j = 0;
	
	while(i < count){
		j = i + 1;
		mc[i] = 1;
		while(j < count){
			if (ms[j] == ms[i]){
				for(k = j; k < count - 1; k++)
					ms[k] = ms[k+1];
			count--;
			mc[i]++;
			} else j++;
				
		}
	i++;
	}
	
	for(i = 0; i < count; i++)
		printf("%c ,",ms[i]);
	printf("\n");
	for(i = 0; i < count-1; i++)
		printf("%d ,",mc[i]);
	
}
goto ∞ вне форума Ответить с цитированием
Старый 03.07.2017, 18:20   #2
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Цитата:
Сообщение от goto ∞ Посмотреть сообщение
Правильно ли так делать или возможно сделать по легче.
- Конечно можно. Один массив правильно - просто последовательность значений(символов). Второй массив - классов или структур. Структура(класс) будет содержать 2 элемента: сам символ(char) и количество его повторений(int).
Потом в конце выводишь просто второй массив на печать и все!:D
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.
Cuprum5 вне форума Ответить с цитированием
Старый 03.07.2017, 18:23   #3
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Цитата:
Сообщение от goto ∞ Посмотреть сообщение
while( (c = getchar()) != EOF){
- файлы здесь нипричем, Вы же из консоли вводите.
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.
Cuprum5 вне форума Ответить с цитированием
Старый 03.07.2017, 18:33   #4
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Цитата:
Сообщение от goto ∞ Посмотреть сообщение
Код:
for(k = j; k < count - 1; k++)
	ms[k] = ms[k+1];
- вот это я не понял зачем делать. Изменяете исходный массив же ведь. Правильно? Я чувствую, что тут надо все программу переписывать по моей идее.:D
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.
Cuprum5 вне форума Ответить с цитированием
Старый 03.07.2017, 18:35   #5
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Аааааааааааа, понял теперь, удаляете повторяющиеся элементы. Сделайте по моей идее, да не мучайтесь.
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.
Cuprum5 вне форума Ответить с цитированием
Старый 03.07.2017, 18:41   #6
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Цитата:
Сообщение от goto ∞ Посмотреть сообщение
Код:
while(j < count)
{
	if(ms[j] == ms[i])
        {
		for(k = j; k < count - 1; k++)
			ms[k] = ms[k+1];
	count--;
	mc[i]++;
       }
       else j++;
}
- неправильный алгоритм работы. Из Вашего сообщения я понял, что нужно считать повторения только повторяющихся символов, но в Вашей реализации он проходит до конца массива(переменная j). Если же считать только повторяющиеся символы, то при несовпадении символов в ветке else должен быть break.
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.
Cuprum5 вне форума Ответить с цитированием
Старый 03.07.2017, 18:48   #7
goto ∞
Форумчанин
 
Аватар для goto ∞
 
Регистрация: 21.12.2010
Сообщений: 155
По умолчанию

Цитата:
Сообщение от Cuprum5 Посмотреть сообщение
- неправильный алгоритм работы. Из Вашего сообщения я понял, что нужно считать повторения только повторяющихся символов, но в Вашей реализации он проходит до конца массива(переменная j). Если же считать только повторяющиеся символы, то при несовпадении символов в ветке else должен быть break.
Это алгоритм удаления повторяющихся элементов, если прерывать то никак не получить количество повторений какого либо символа.
goto ∞ вне форума Ответить с цитированием
Старый 03.07.2017, 18:50   #8
goto ∞
Форумчанин
 
Аватар для goto ∞
 
Регистрация: 21.12.2010
Сообщений: 155
По умолчанию

Цитата:
Сообщение от Cuprum5 Посмотреть сообщение
- файлы здесь нипричем, Вы же из консоли вводите.
В консоли тоже можно поставить символ конца файла, Ctrl+z но это не суть
goto ∞ вне форума Ответить с цитированием
Старый 04.07.2017, 08:38   #9
Cuprum5
Форумчанин
 
Регистрация: 09.05.2017
Сообщений: 735
По умолчанию

Он считает сколько символов вообще входит в строку? А не только повторяющиеся подряд?
Еще я хотел посоветовать, что лучше бы исходный массив завести массив символов и целые переменные можно заводить через запятую. Т.е. вот так:
Код:
int main()
{
	char ms[MAX];
	int count, c, i, j, k, mc[MAX];
Напишу программу на C++ и Asm для AVR. Черчение: sergeisky@yahoo.com.

Последний раз редактировалось Cuprum5; 04.07.2017 в 12:18.
Cuprum5 вне форума Ответить с цитированием
Старый 04.07.2017, 17:33   #10
goto ∞
Форумчанин
 
Аватар для goto ∞
 
Регистрация: 21.12.2010
Сообщений: 155
По умолчанию

Цитата:
Сообщение от Cuprum5 Посмотреть сообщение
Он считает сколько символов вообще входит в строку? А не только повторяющиеся подряд?
Еще я хотел посоветовать, что лучше бы исходный массив завести массив символов и целые переменные можно заводить через запятую. Т.е. вот так:
Код:
int main()
{
	char ms[MAX];
	int count, c, i, j, k, mc[MAX];
Только повторяющиеся
Не вижу смысла поменять массив типа int на тип char
goto ∞ вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Задачка из К&Р goto ∞ Общие вопросы C/C++ 2 02.07.2017 15:22
не перегружается ostream& operator<<(ostream &, Card&) Antej Общие вопросы C/C++ 2 17.12.2012 14:02
Вопрос по поводу меню на сайте, html&css&js antoxa22 HTML и CSS 14 30.12.2011 11:02
TForm & TImage & PNG & Прозрачность delphi_beginner Общие вопросы Delphi 7 19.09.2009 08:46