Как стать автором
Обновить

Комментарии 36

Начинать с двух точек много, чтобы разобраться в кривых разного порядка лучше начинать с 1 точки. Так нагляднее. Верхнее ограничение тоже забавно — неужели есть необходимость разбираться с такими сложными кривыми? Если по фану, то сделали бы 100 — красивые штуки хоть получались бы — например развязку в Москве нарисовать можно было бы.
Я бином делал по простому, через факториал, чтобы переполнение не вызывать ограничил тринадцатью опорными точками. Можно сменить типы в расчетах в исходниках и увеличить количество.

private int Factorial(int i)
{
    int ret = 1;
    while (i > 1) ret *= i--;
    return ret;
}

Красивее так:

private int Factorial(int i)
{
    if (i == 0) return 1;
    return i * Factorial(i--);
}

Извините за занудство.
спорный вопрос. бытует мнение, что несколько выходов (aka return) из функции не есть комильфо, посему через переменную как-то правильнее. тем более ваш вариант с рекурсией, совсем уж извращенство. хочется «красоты», в этом смысле, используйте лямбда выражения :)
Ну с несколькими ретурнами — это тема для холиваров. Я чаще встречаю людей, кто так не считает, чем кто так считает. Вроде, это устаревшее мнение, берущее корни из Паскаля в силу определённых нюансов.
Как мне кажется, функциональное программирование действительно красиво. А лямбда — это еще не ФП. Зато представленный пример с рекурсией как раз «в духе» ФП. И уж никак не извращенство.
Про рекурсию я негативно отзывался лишь конкретно в данном примере. Сама по себе она не плохая штука.
тогда уж:
private int Factorial(int i)
{
    return i == 0 ? 1 : i * Factorial(i-1);
}
Соглашусь с вышесказанным, рекурсия для такой простой задачи — как-то не к месту, что ли.

Зачем усложнять тривиальные вещи? Пожалейте stack :)
В данном случае вообще нет необходимости считать факториал, можно забить табличку от 0 до 20, 21! уже не влезет в int64.
Так и сделано, при выборе количества точек биномиальный коэффициент для них вычисляется один раз и заносится в табличку. Откуда при расчетах и берется. Конечно можно совсем статически табличку забить, но это немного усложнит расчет и сделает его менее читабельным, а на производительность не повлияет.
Если среда выполнения поддерживает «хвостовую рекурсию», то stack чувствует себя очень хорошо при подобных вариантах. Да и скорость не хуже.

А запись через рекурсию более точно подходит под математическое определение факториала.

Так почему бы не записать так, чтоб понятно было даже «доменному специалисту» (в данном случае — математику)? :)
Зачем усложнять тривиальные вещи?

Зачем усложнять тривиальные вещи, если можно использовать рекурсию вместо цикла? ;)
Имхо, всему своё место.
Написал специально без рекурсии, на случай расширения, чтобы в будущем стек не забивать)
Вот только ваш код не работает.
А подробнее? У меня почему то все работает. Какая ошибка? Алгоритмическая, программная, и где?
Постфиксный декремент.
Нужен префиксный:
private int Factorial(int i)
{
    if (i == 0) return 1;
    return i * Factorial(--i);
}

а еще лучше:
private int Factorial(int i)
{
    if (i == 0) return 1;
    return i * Factorial(i-1);
}
Не посмотрел к какому комменту ваш ответ, подумал про свой код.)
В 4 часа ночи писал. Спасибо Вам за поправку, а остальным — за ценные комментарии. Мне есть еще чему учиться.
Не нашёл своего варианта с тернарным оператором. Видимо «Lazy Python Programmer».
Ваш вариант не содержит хвостового вызова и потому в языках с его оптимизацией оптимизирован не будет
А в .Net (точнее в C#) лучше рекурсию не использовать вовсе, поскольку там нет оптимизации хвостовых вызовов на уровне компилятора. Хотя в CLR инструкция все же присутсвует. Хотя может со времен .NET 3.5 что-то изменилось, честно не в курсе.

Хотя применительно в данному примеру это неважно, поскольку здесь не такая большая глубина, чтобы заметить разницу или получить StackOwerflow
Понял я уже, что в 4 утра спать надо, а не умничать. :) С университета просто отложилось в памяти, что факториал считается рекурсивной функцией.
Рекурсией тоже надо уметь правильно пользоваться ;)
private static Int64 Factorial(int n)
{
    // Due to Int64 limits
    if (n > 20)
    {
        throw new ArgumentException("Factorial parameter can not be greater than 20.", "n");
    }

    if (n == 0)
    {
    	return 1;
    }
	
    Int64 result = 1;
    for (int i = 1; i <= n; i++)
    {
        result *= i;
    }
	
    return result;
}
Забыл проверку на отрицательные числа.
Вообще, если уж считать бином — то лучше бы сделать оптимизации, позволяющие не ограничиваться влезанием полного факториала в разрядную сетку.
ifolder? Неужели не существует нормальных файл-хостингов?
Если знаете лучше, дайте линк. ifolder пока не подводил.
Смотреть рекламу и ждать чтобы скачать файл — это нормально? Используйте zalil.ru или rghost.
По этой причине я передумал качать файл))
Честно говоря не вижу причины не создать проект на том же code.google.com — сорсы залить в Mercurial, а откомпилинную версию в Downloads

Имхо не намного сложнее чем на всякие файло-помойки, зато возможностей намного больше.
у вас нет дропбокса? а в дропбоксе нету шары?
Нет, более того о дропбоксе и не знал.
Если автор не против, то вот, сделал небольшой «косметический ремонт»
Автор совершенно не против и согласен.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации