Перейти к содержимому

Сервис обмена электронных валют


Функция fact

#1 Banderas

Banderas
  • Пользователь
  • 1 168 сообщений
  • Репутация: 1
0

Отправлено 26 Апрель 2009 - 13:35

Для начала хочу спросить, какое число обозначает $x? Я так понял, что оно задается значением предыдущего? Например у меня при коде
<?php
function fact($x)
{
if ($x==0) return 1;
else return $x*fact($x-1);
}

echo fact(5);
?>
получается, что когда введу в fact(4), то получается 24, логически подумать 6*4=24, значит значение $x должно быть число 6. Но потом прописываю fact(5) и теперь число не 6*5=30, а 120 => 24*5=120. Никак не могу понять как действует этот fact() :D


Я по чуть-чуть практикуюсь и решил попробовать чтобы выводило значение fact(число) рандомно, но ошибка

Fatal error: Cannot redeclare rand() in Z:\home\localhost\www\admin\func.php on line 17


Где я "провтыкал", или вообще, код правильно написан?
<?php

function fact($x)
{
if ($x==0) return 1;
else return $x+fact($x-1);
}

function Rand()
{
$mas = array ();
mt_srand (time());

for ($i=0; $i<10; $i++)

$mas [] = mt_rand(0, 10);

return $mas;
}

$A = Rand();
foreach ($A as $K=>$V);

echo fact($V);
?>

 

 

  • 0


#2 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 26 Апрель 2009 - 15:06

Banderas, разберем первый код:
<?php

// наша функция
function fact($x)
{
   if ($x==0) return 1; // если в функцию поступило нулевое число, то 1
   else return $x*fact($x-1); // иначе аргумет * возвращенный результат от этой же функции с аргументом на 1 меньше
}

echo fact(5); // печатаем результат

?>

fact(1) - результат: 1

1) Вызываем функцию с $x = 1
2) Проверка ложна, возвращаем 1 * результат из функции fact(0)
3) fact(0) - $x = 0
4) Проверка истинна, возвращаем 1

Получаем ответ: 1 * 1 = 1

fact(2) - результат: 2

1) Вызываем функцию с $x = 2
2) Проверка ложна, возвращаем 2 * результат из функции fact(1)
3) fact(1) - $x = 1
4) Проверка ложна, возвращаем 1 * результат из функции fact(0)
5) fact(0) - $x = 0
6) Проверка истинна, возвращаем 1

Получаем ответ: 2 * (1 * 1) = 2

fact(3) - результат: 6

1) Вызываем функцию с $x = 3
2) Проверка ложна, возвращаем 3 * результат из функции fact(2)
3) fact(2) - $x = 2
4) Проверка ложна, возвращаем 2 * результат из функции fact(1)
5) fact(1) - $x = 1
6) Проверка ложна, возвращаем 1 * результат из функции fact(0)
7) fact(0) - $x = 0
8) Проверка истинна, возвращаем 1

Получаем ответ: 3 * (2 * (1 * 1)) = 6

fact(5) - результат: 120

1) Вызываем функцию с $x = 5
2) Проверка ложна, возвращаем 5 * результат из функции fact(4)
3) fact(4) - $x = 4
4) Проверка ложна, возвращаем 4 * результат из функции fact(3)
5) fact(3) - $x = 3
6) Проверка ложна, возвращаем 3 * результат из функции fact(2)
7) fact(2) - $x = 2
8) Проверка ложна, возвращаем 2 * результат из функции fact(1)
9) fact(1) - $x = 1
10) Проверка ложна, возвращаем 1 * результат из функции fact(0)
11) fact(0) - $x = 0
12) Проверка истинна, возвращаем 1

Получаем ответ: 5 * (4 * (3 * (2 * (1 * 1)))) = 120

Надеюсь понятен результат работы. Это один из видов рекурсии(функция вызывается в своём же теле). Если условия никакого не будет, получится зацикленный результат. Поэтому как мы видим, как только аргумент функции будет = 0, рекурсия больше вызваться не будет.

------------------------------------------------------------------------------

Твоя функция называется Rand(), а не rand()

Никогда не делай лишних отступов:
<?php

function fact($x)
{
   if ($x==0) return 1;
   else return $x+fact($x-1);
}

function Rand()
{
   $mas = array();
   mt_srand (time());
   for ($i=0; $i<10; $i++)
	  $mas [] = mt_rand(0, 10);
   return $mas;
}

/* работа скрипта */
$A = array(); // нужно для правильности(чтобы была понятна структура кода)
$A = Rand(); // создаём random массив
foreach ($A as $K=>$V) //; тут не нужна
   echo fact($V); // Выводим факториал random чисел
?>

  • 0

#3 Banderas

Banderas
    Topic Starter
  • Пользователь
  • 1 168 сообщений
  • Репутация: 1

Отправлено 26 Апрель 2009 - 15:31

Огромное спасибо, все понял! Вот так должны в книгах писать, ато там пишут как для себя - программистов.

У меня и было Rand() а не rand(). И твой код не работает, ошибка та же, строка 16.


пс. ты 2 раза написал fact(3)
  • 0


#4 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 26 Апрель 2009 - 16:21

Banderas, извиняюсь... Это я натупил.

Fatal error: Cannot redeclare rand() in Z:\home\localhost\www\admin\func.php on line 17

Фатальная ошибка: Нельзя переопределить rand() в ... строка 17
Так как rand() это стандартная функция, а в php нет возможности переопределения функции, она ругается, что данная функция определена 2 раза. Стоит поменять имя на другое(незарезервированное) и всё заработает.
  • 0

#5 Banderas

Banderas
    Topic Starter
  • Пользователь
  • 1 168 сообщений
  • Репутация: 1

Отправлено 26 Апрель 2009 - 16:33

Теперь все работает =) Ещё один вопрос, как максимально rand’омировать mt_srand, если можно так выразиться... Пробовал
mt_srand (time() * microtime());
не помагает :D
  • 0


#6 ZiTosS

ZiTosS
  • Пользователь
  • 5 148 сообщений
  • Репутация: 8

Отправлено 26 Апрель 2009 - 16:42

Попробуй...
function Rand() {
   $mas = array();
   for ($i=0; $i<10; $i++)
   {
	  mt_srand (time());
	  $mas [] = mt_rand(0, 10);
   }
   return $mas;
}

  • 0

#7 Banderas

Banderas
    Topic Starter
  • Пользователь
  • 1 168 сообщений
  • Репутация: 1

Отправлено 26 Апрель 2009 - 16:59

Не спасло, вот так помогает:
function tRand()
{
$mas = array ();
$k = mt_rand(0, 99);
mt_srand (time()*(double)microtime()*$k);

for ($i=0; $i<10; $i++)

$mas [] = mt_rand(0, 10);

return $mas;
}

  • 0



Оформление форума – IPBSkins.ru