- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
class Program
{
static void Main()
{
UInt64 num;
Console.WriteLine(num = F(Convert.ToUInt64(Console.ReadLine())));
Main();
}
static UInt64 F(UInt64 number)
{
return number <= 0 ? 1 : number * F(number - 1);
}
}
UInt64 num;
Console.WriteLine(num = F(Convert.ToUInt64(Console.ReadLine()))) ;
Эклипс уже бы матюкнулся наверно
F() вызов рекурсивной функции всё остальное тоже нормально
а рекурсивный вызов Main() это говнокод с переполнением стэка от бесконечной рекурсии
Кстати, а шарп хвостовую рекурсию оптимизирует?
Иногда алгоритмы ощутимо проще выразить (и корректно написать с первого раза) хвостовой рекурсией, чем циклом.
vs
На более сложных примерах профит может быть более заметным. Быстрое возведение в степень: В какой версии проще проверить, что a * b ^ n == const?
pow(1, 1, Int64.MaxValue)
тебе стек распидорасит, а с циклом он хотя-бы не упадёт и вообще
деление тут не нужно
Я вставил деление, чтобы пидар на умножение/деление сдвигами снова не вонял.
> тебе стек распидорасит, а с циклом он хотя-бы не упадёт
Опять умник появился? тред не читай @ комментируй очевидное
Ты обсуждение про tail call recursion optimization читал?
Ну и глубина рекурсии даже в твоём случае не будет больше 64. Алгоритм логарифмический.
Переменная-накопитель нужна лишь для нерекурсии.
Я умышленно написал так, чтобы вменяемый компилятор мог применить tail call recursion optimization и превратить рекурсивный код в цикл.
На SO говорят, что нет
ну а хули? программисту же, кроме как иль мерджить, делать нехуй
Типа, функциональщики пушит (нормально) с хвостовой рекурсией или (через жопу) с Enumerable