function Factorial($x)
{
if ($x < 1)
{
echo "Factorial() Error: Number too small!";
}
Это неправильно, 0! = 1
определено, поэтому тест должен быть $x < 0
.
$ans = 1;
for ($xx = 2; $xx >= $x; $xx++)
Вы опечатали условие, оно должно быть $xx <= $x
.
function Combination($selectcount,$availablecount)
{
$ans = Factorial($availablecount) / (
Factorial($availablecount - $selectcount) * Factorial($selectcount)
);
return ($ans);
}
Здесь у вас есть две потенциальные проблемы:
- вызов функции
Factorial
медленнее, чем цикл, вычисляющий здесь число комбинаций - факториалы становятся большимибыстро, так что вы рискуете переполниться и получить неточности там, где вам не нужно
То, являются ли это настоящими проблемами, зависит от вашего приложения.Вы написали, что результаты попадают в массив, предположительно, чтобы избежать пересчета, поэтому скорость для начального расчета менее важна.Однако проблемы переполнения вполне могут быть.Чтобы избежать этого, вычислите записи массива рекурсивно по треугольнику Паскаля, choose(n+1,k) = choose(n,k) + choose(n,k-1)
, где choose(n,k) = 0
, если k < 0
или k > n
.Кроме того, вы можете рассчитать каждую строку, начиная с choose(n,0) = 1
и choose(n,k) = choose(n,k-1)*(n+1-k)/k
для 1 <= k <= n
.Оба метода избегают большого промежуточного значения n!
и, таким образом, дают точные результаты для более широкого диапазона чисел.