Основной рекурсивный метод - факториал

Я практикую рекурсию и не понимаю, почему этот метод не работает. Любые идеи?

    public void fact()
    {
        fact(5);
    }

    public int fact(int n)
    {
        if(n == 1){
            return 1;
        }
        return n * (fact(n-1));
    }
}

Спасибо


person bob    schedule 10.05.2010    source источник
comment
Что именно вы имеете в виду не работает? Что он делает и чего вы от него ожидали?   -  person Justin Ethier    schedule 10.05.2010


Ответы (7)


Кажется, ваш код работает, но вы ничего не делаете с возвращаемым значением, поместите вызов метода fact или fact(5) внутри System.out.println и посмотрите, что вы получите.

person Anthony Forloney    schedule 10.05.2010

Часть рекурсии в порядке; вы просто не используете его значение return, которое отбрасывается. Вот полное Java-приложение вашего факторного кода, слегка подправленное для образовательных целей:

public class Factorial {
    public static String fact(int n) {
        if(n == 1){
            return "1";
        }
        return n + " * " + (fact(n-1)); // what happens if you switch the order?
    }
    public static void main(String[] args) {
        System.out.println(fact(5));
        // prints "5 * 4 * 3 * 2 * 1"
    }
}
person polygenelubricants    schedule 10.05.2010

Упрощенная версия вашего кода:

public int fact(int n)
{
    if(n == 1){
        return 1;
    }
    return n * (fact(n-1));
}

может быть просто:

public int fact(int n)
{
    return n == 1 ? 1 : n * fact(n - 1);
}

но ваш код не является неправильным, это просто другой стиль (если вы не привыкли к тернарному оператору, оставьте его таким, какой он есть). В этих случаях я предпочитаю использовать тернарный оператор (обратите внимание, что код не имеет побочных эффектов).

person Jonas Fagundes    schedule 10.05.2010
comment
В алгоритме нет ничего плохого, как сказали 3 других автора 7 часов назад. ОП просто не выполнял никакого вывода программы. - person Charlie Salts; 11.05.2010
comment
Но его стиль кода сбивает с толку. Две точки выхода, неявный else и ненужные скобки. Это моя точка зрения. Вопрос более чем решен. - person Jonas Fagundes; 11.05.2010
comment
Ничего страшного в двух возвратах нет. Кроме того, новичку, вероятно, будет сложно понять, как использовать условный оператор. - person helpermethod; 13.05.2010

Работает отлично. Вы ничего не назначаете. Вот тест, который докажет, что это работает.

@Test
public void testYourFactorialMethod() {
    assertEquals(120, fact(5));
}
person andyczerwonka    schedule 10.05.2010
comment
Разве assertEquals() не является методом JUnit API? Я предполагаю, что JUnit еще не включен здесь, поэтому вам, вероятно, следует быть немного более явным. Если это обычный метод API, мне вину. - person Pops; 10.05.2010
comment
Да, это JUnit, и все, что я пытаюсь показать, это то, что его метод работает. Если вы читаете мой комментарий, я не предлагаю ему куда-либо вставлять мой код. - person andyczerwonka; 10.05.2010

Попробуйте что-то вроде этого: (Или, может быть, попробуйте это напрямую)

public class factorial {

    private static int factorial( int n ){
        if (n > 1)  {
            return n * (factorial(n-1));
        } else {
            return 1;
        }
    }

    public static void main(String[] args) {
        System.out.println(factorial(100));
    }
}
person Alex Mapley    schedule 04.10.2016

static int factorial(int x) {    
    int result;    
    if (x == 1) {    
        return 1;    
    }    
    // Call the same method with argument x-1    
    result = factorial(x – 1) * x;    
    return result;    
}

Для полного примера проверьте это

http://answersz.com/factorial-program-in-java-using-recursion/

person Amruth M Raj    schedule 30.12.2014

Совершенно неправильно писать Фибоначчи рекурсивными методами!!

Это старый известный пример того, как хороший/плохой алгоритм влияет на любой проект.

если вы пишете рекурсию Фибоначчи, для вычисления 120 вам нужно 36 лет, чтобы получить результат!!!!!!

public static int Fibonacci(int x)
{  // bad fibonacci recursive code
if (x <= 1)
      return 1;
return Fibonacci(x - 1) + Fibonacci(x - 2);
}

в dot net 4.0 есть новое имя типа BigInteger, и вы можете использовать его для улучшения функции.

с помощью системы; используя System.Collections.Generic; используя System.Numerics; // нужна ссылка. к этому собранию

namespace Fibonaci
{
 public class CFibonacci
 {
   public static int Fibonacci(int x)
   {
       if (x <= 1)
           return 1;
       return Fibonacci(x - 1) + Fibonacci(x - 2);
   }

   public static IEnumerable<BigInteger> BigFib(Int64 toNumber)
   {
       BigInteger previous = 0;
       BigInteger current = 1;

       for (Int64 y = 1; y <= toNumber; y++)
       {
           var auxiliar = current;
           current += previous;
           previous = auxiliar;
           yield return current;
       }
   }
 }
}

и вы можете использовать его как

using System;
using System.Linq;

namespace Fibonaci
{
 class Program
 {
   static void Main()
   {
       foreach (var i in CFibonacci.BigFib(10))
       {
           Console.WriteLine("{0}", i);
       }

       var num = 12000;
       var fib = CFibonacci.BigFib(num).Last();
       Console.WriteLine("fib({0})={1}", num, fib);

       Console.WriteLine("Press a key...");
       Console.ReadKey();
   }
 }
}

и в этом случае вы можете вычислить 12000 менее чем за секунду. так

Использование рекурсивных методов не всегда является хорошей идеей

Вышеприведенный код импортирован из блога Вахида Насири, написанного на персидском

person Nasser Hadjloo    schedule 10.05.2010
comment
на чей вопрос ты здесь отвечаешь? - person Hendrik; 10.05.2010
comment
Разве он не занимается Факториалом, а не Фибоначчи? - person corsiKa; 10.05.2010
comment
-1: Хотя рекурсия не может быть оптимальным способом написания факторного метода, это является простым примером для введения концепции рекурсии. Не делайте предположений о том, почему спрашивающий задает вопрос. Кроме того, вычисление 120 происходит из факта (5); это, конечно, не займет 36 лет, чтобы обработать. - person Pops; 10.05.2010
comment
Ваш алгоритм требует времени O(n) для вычисления Fibonacci(n), что ужасно плохо. Ваш комментарий показывает, что проблема не в рекурсии и не в итерации. Проблема в использовании хорошего алгоритма. - person sigfpe; 10.05.2010