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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 13.02.2017, 19:21   #1
Кристина1998
Форумчанин
 
Регистрация: 01.11.2016
Сообщений: 110
По умолчанию Объяснить(прокомментировать)строки программы - C (СИ)

Написать генератор псевдослучайных чисел по алгоритму f[n] = (f[n - 1] + f[n - 2] + f[n - 3]) % 239;f(0)=f(1)=f(2)=30.Посчитать частоту каждого числа при выборке 100000
int gen(int n)
{
static unsigned int f[100000] = { 30, 30, 30 };
if (n >= 0 && n <= 2)
return 30;
f[n] = (f[n - 1] + f[n - 2] + f[n - 3]) % 239;
return f[n];
}


int main()
{
int a[239] = { 0 };
for (int i = 0; i < 100000; i++)
a[gen(i)]++;
for (int i = 0; i < 239; i++)
printf("Chastota chisla %d ravna %d\n", i, a[i]);
return 0;
}
Кристина1998 вне форума Ответить с цитированием
Старый 14.02.2017, 05:39   #2
ura_111
Участник клуба
 
Регистрация: 14.05.2016
Сообщений: 1,793
По умолчанию

Я пишу не очень красиво: ошибки, частые разрывы логики-нити (я завидую тем людям, которые могут ясно, компактно, лаконично объяснить свою мысль), поэтому обычно я форумчанам советую перечитывать мои посты по 3-ри раза, но к тебе "особые условия" - читать 5-раз (не меньше).

1) Остаток от деления, например на "3":
Код:
1%3=1
2%3=2
3%3=0
4%3=1
5%3=2
6%3=0
..........
..........
Обрати внимание - не превосходит "3-х"... Так вот, аналогично "...%239", какое бы число не генерировалось функции f() - остаток от деления на 239 даст всегда число в промежутке 0 - 288. Поэтому и формируется массив из "int a[239]" (по законам С++, счёт идёт с 0-ля, а последний символ зарезервирован за символом конца последовательности, т.е. фактически можно обратится только к элементам массива: a[0] - a[238]=...). Улавливаешь связь? Проанализируй:

10.jpg

Это подсчитывается тут:
Код:
int a[239] = { 0 };
for (int i = 0; i < 100000; i++)
a[gen(i)]++;
Запускается цикл на 100000 генераций; на каждом шаге функция "gen(i)" (о самой функции - будет ниже) возвращает значение псевдослучайного числа, - и используется как индекс массива "а[239]". Подсчёт осуществляется "++".

___________________________________ ___________________________

Ну это просто, вывод результата на экран:
Код:
for (int i = 0; i < 239; i++)
printf("Chastota chisla %d ravna %d\n", i, a[i]);
___________________________________ ___________________________

Теперь о функции:
Код:
int gen(int n)
{
static unsigned int f[100000] = { 30, 30, 30 };
if (n >= 0 && n <= 2)
return 30;
f[n] = (f[n - 1] + f[n - 2] + f[n - 3]) % 239;
return f[n];
}
Функция принимает номер генерации "n", которая здесь становится индексом массива (массив имеет свойство "static" - это важно, но потом)... Особенность функции "f[n] = (f[n - 1] + f[n - 2] + f[n - 3])", является то что она зависит от трёх предыдущих значениях (возьми выпиши на листочке бумаги чему равно "f[n]" от 0-ля до 10-ти). Отсюда появляется проблема - чему равно, например "f[2]":
Код:
f[2] = f[1] + f[0] + f[- 1] ???????
Элемент массива с индексом "f[- 1]", но нумерация должна начинаться с 0-ля... По этой причине задаётся первые три элемента массива:
Код:
f[100000] = { 30, 30, 30 };
ну а остальные можно рассчитывать, например:
Код:
f[3] = f[2] + f[1] + f[0]=....
f[4] = f[3] + f[2] + f[1]=....
f[5] = f[4] + f[3] + f[2]=....
.....................................
......................................
f[100000] = f[99999] + f[99998] + f[99997]=....
Поэтому нужно это искусственное реагирование на первые 3-ри индекса (n= 0, 1, 2):
Код:
if (n >= 0 && n <= 2)
return 30;
Ключевое слово "return" оборвёт дальнейшее выполнение функции "int gen(int n)" и вернёт в "main" 30. Вместо "30" красивее было бы написать "f[n]" - понимаешь и там "return f[n];" и там.
___________________________________ ____________________

Первые три значения функции "f[n]" рассмотрели, ну а дальнейшие 99997 раза вызова расчёт идёт уже по формуле:
Код:
f[n] = (f[n - 1] + f[n - 2] + f[n - 3]) % 239;
и возврат в "main" того что рассчитали:
return f[n];
___________________________________ ________________________
Ну и последний элемент здесь - ключевое слово "static". Что это значит?
Память под массив выделяется один раз и держится в оперативной памяти до конца работы всей программы. Напомню, обычно (без этого слова) этот массив бы создавался бы всякий раз при вызове функции из "main" (т.е. все 100000 раз). Ну возврат первых 3-х раз не изменилось бы, а вот остальные возвраты уууууууу. Возьми поэкспериментируй: удали слово "static" и запусти. Что вывело? Внимательно анализируй результат (там не только будут нули!).
Вместо слова "static" можно было бы сделать массив "unsigned int f[100000]" глобальным:
Код:
unsigned int f[100000] = { 30, 30, 30 };
int gen(int n)
{
	if (n >= 0 && n <= 2)
......................
......................

Последний раз редактировалось ura_111; 14.02.2017 в 05:49.
ura_111 вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Объяснить код программы Morreaw Помощь студентам 0 09.06.2015 09:11
Прокомментировать каждую строку программы cudri Помощь студентам 2 29.05.2013 14:02
Прокомментировать код программы lolbox C# (си шарп) 0 24.03.2013 10:11
C# - прокомментировать код программы шифрования магическим квадратом Darh Помощь студентам 0 07.11.2012 10:48
Объяснить с++ программы МихаилД Фриланс 3 26.06.2012 03:06