2013-11-23 1 views
1

Мне нужно написать рекурсивный метод для вычисления следующих серий: e = 1 + 1/1! +1/2! +1/3! + ...добавление фракций с использованием рекурсии e = 1 + 1/1! +1/2! +1/3! +

Это то, что у меня есть до сих пор.

public static void main(String[] args) 
{ System.out.println("enter n :"); 
    int n =scan.nextInt(); 
    double h = fact(n); 
    System.out.println(" e = "); 
} 
public double fact(int n) 
{ 
    if (n == 1) 
     return 1; 
    else 
     return ???; 
    } 
} 
+1

http://en.wikipedia.org/wiki/Factorial См определение по рекуррентным соотношением. – zch

+0

В чем вопрос? – superuser

+0

@superuser "нужно написать рекурсивный метод для вычисления следующих рядов: e = 1 + 1/1! +1/2! +1/3! +." – Woot4Moo

ответ

0

Вот несколько ресурсов:

Math is fun

«Да вы можете, но вам необходимо войти в тему называется!„Гамма Function“, который находится за пределами этого простая страница.

Половина Факториал

Но я могу вам сказать, тот факт, orial половины (½) составляет половину квадратного корня пи = (½) √π, и поэтому некоторые «полуцелые» факториалов являются:»

Более конкретно вы хотите Gamma Function

Apache commons имеет реализацию этой функции.

Обсуждение Math Exchange

А вот реализация от Princeton

public class Gamma { 

    static double logGamma(double x) { 
     double tmp = (x - 0.5) * Math.log(x + 4.5) - (x + 4.5); 
     double ser = 1.0 + 76.18009173 /(x + 0) - 86.50532033 /(x + 1) 
         + 24.01409822 /(x + 2) - 1.231739516 /(x + 3) 
         + 0.00120858003/(x + 4) - 0.00000536382/(x + 5); 
     return tmp + Math.log(ser * Math.sqrt(2 * Math.PI)); 
    } 
    static double gamma(double x) { return Math.exp(logGamma(x)); } 

    public static void main(String[] args) { 
     double x = Double.parseDouble(args[0]); 
     System.out.println("Gamma(" + x + ") = " + gamma(x)); 
     System.out.println("log Gamma(" + x + ") = " + logGamma(x)); 
    } 

} 
3

Таким образом, предполагая, что n вход вы принимаете является отправным знаменатель наименьшей фракции вы хотите добавить ...

(к примеру, учитывая n = 10, вы хотите добавить 1 через 1/10)

Затем вам нужно настроить метод так, что при вызове fact(10), он собирается вернуть сумму 1/10 плюс результат fact(9), или в более общем плане, 1/n + fact(1/n-1);

Итак, вы ищете что-то вроде это:

public double fact(int n) { 
    if (n < 0) { 
     return 0.0; 
    } else if (n == 0) { 
     return 1.0; 
    } else { 
     return (1.0/n + fact(n-1)) 
    } 
} 

Также обратите внимание на изменения в базовых корпусах. Когда n < 0, мы просто return 0.0, потому что, если я правильно помню, факториал любого отрицательного числа всегда равен 0, правильно?

Между тем, базовый корпус должен быть n==0, а не n == 1. Ваша серия начинается с 1 + 1/1. Обратите внимание, что 1 не является 1/0 или 1/nothing, это всего лишь 1/1. Мы не можем вернуть 1/n, если n - 0. Для правильного вычисления серии мы должны добавить первый возврат первого элемента серии в случае n = 0.

И имейте в виду, как и все рекурсивные функции, очень большие значения n вызовет переполнение стека.

+0

hmm это не удается на n == 1. 1! == 1 не 2. также это повторяется навсегда, потому что вход 0 сделает его бомбой. – Woot4Moo

+0

ближе. Но я думаю, что вы хотите, чтобы это было, если '(n <0)' с .5! не равна нулю. И мы можем отбросить негативные негативы – Woot4Moo

+0

Метод принимает аргумент 'int'. Вы не можете отправить его '.5'. Java интерпретирует '.5' как' 0'. – nhgrif

0

Вычисление e^n рекурсивно очень дорого. Это O (n^2), и трудно остановиться, когда остановиться. Вместо этого я предлагаю вам сделать это итеративно.

static final int runs = 20000; 
static volatile int exp = 1; 
static volatile int n = 18; 
static volatile double dontOptimiseAway; 

public static void main(String[] args) throws InterruptedException { 
    System.out.println("Math.exp(1)=" + Math.exp(1)); 
    System.out.println("exp_iter(18)=" + exp_iter(18)); 
    System.out.println("exp_recurse(18)=" + exp_recurse(18)); 

    for (int t = 0; t < 3; t++) { 
     System.out.printf("exp(1), exp_iter(18), exp_recurse(18) took %,d/%,d/%,d ns on average%n", 
       timeMathExp(), timeExpIter(), timeExpRecurse()); 
    } 
} 

public static long timeMathExp() { 
    long start = System.nanoTime(); 
    for (int i = 0; i < runs; i++) 
     dontOptimiseAway = Math.exp(exp); 
    return (System.nanoTime() - start)/runs; 
} 

public static long timeExpIter() { 
    long start = System.nanoTime(); 
    for (int i = 0; i < runs; i++) 
     dontOptimiseAway = exp_iter(n); 
    return (System.nanoTime() - start)/runs; 
} 

public static long timeExpRecurse() { 
    long start = System.nanoTime(); 
    for (int i = 0; i < runs; i++) 
     dontOptimiseAway = exp_recurse(n); 
    return (System.nanoTime() - start)/runs; 
} 

public static double exp_iter(int n) { 
    double exp = 0, x = 1; 
    for (int i = 2; i <= n; i++) 
     exp += (x /= i); 
    return 2 + exp; 
} 

public static double exp_recurse(int n) { 
    return n <= 0 ? 1 : 1.0/fact(n) + exp_recurse(n - 1); 
} 

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

печатает

Math.exp(1)=2.718281828459045 
exp_iter(18)=2.718281828459045 
exp_recurse(18)=2.7182818284590455 
exp(1), exp_iter(18), exp_recurse(18) took 111/191/760 ns on average 
exp(1), exp_iter(18), exp_recurse(18) took 75/78/558 ns on average 
exp(1), exp_iter(18), exp_recurse(18) took 69/66/552 ns on average 
Смежные вопросы