/* * Modulo: sucessao.c * * Descricao: * Este modulo contem funcoes para calculo de sucessoes famosas. * * Notas: * * Autores: * Manuel Menezes de Sequeira, ISCTE. * * Historia: * Autor: Data: Notas: * MMS 1996/5/9 primeira versao * * Copyright (c) ISCTE, 1996. */ #include "sucessao.h" /* * Funcao: SUCfibonacciRec() * * Accao: * Calcula o valor do elemento n da sucessao de Fibonacci duma forma * recursiva (F(0)=F(1)=1, F(n)=F(n-1)+F(n-2) para n > 1). * * Parametros: * n (E) - numero do elemento da sucessao a calcular. * * Notas: * Se a macro CONTABILIZA estiver definida, a funcao tem um contador * interno de chamadas que pode ser anulado chamando a funcao com argumento * -1, e cujo valor e' devolvido quando a funcao e' chamada com argumento * -2. * * Devolve: * O valor do elemento n da sucessao. */ unsigned long SUCfibonacciRec(int n) { #ifdef CONTABILIZA static unsigned long chamadas = 0; if(n == -1) return chamadas = 0; if(n == -2) return chamadas; chamadas++; #endif if(n < 2) return 1UL; return SUCfibonacciRec(n-1) + SUCfibonacciRec(n-2); } /* * Funcao: SUCfibonacci() * * Accao: * Versao iterativa da funcao anterior. * * Parametros: * n (E) - numero do elemento da sucessao a calcular. * * Notas: * Esta versao nao contabiliza chamadas. * * Devolve: * O valor do elemento n da sucessao. */ unsigned long SUCfibonacci(int n) { int i; unsigned long fn1, fn2, fn; fn = fn1 = fn2 = 1UL; for(i = 2; i <= n; i++) { fn = fn1 + fn2; fn2 = fn1; fn1 = fn; } return fn; } /* * Funcao: SUCnfibonacci() * * Accao: * Funcao que calcula o numero de chamadas N(n) da funcao F(n) * (SUCfibonnaciRec()), versao recursiva. N(n) = N(n-1) + N(n-2) + 1, para * n > 1, e N(0) = N(1) = 1. * * Parametros: * n (E) - numero do elemento da sucessao para o qual calcular o numero * de chamadas. * * Notas: * Mas, como o numero de chamadas a F() (versao recursiva) para calculo * de F(n) e' N(n)=2F(n)-1, esta funcao podia ser mais simples! Ver em * comentario abaixo. A deducao faz-se com facilidade: * 1. F(n) = F(n-1) + F(n-2) n > 1 * 2. 2F(n) = 2F(n-1) + 2F(n-2) n > 1 * 3. 2F(n) - 1 = 2F(n-1) -1 + 2F(n-2) -1 + 1 n > 1 * 4. X(n) = 2F(n) - 1 * de 3. e 4.: * 5 X(n) = X(n-1) + X(n-2) + 1 n > 1 * 6. X(0) = X(1) = 2x1 - 1 = 1 * 7. mas 5. e 6. sao a definicao de N(n)! Logo N(n) = X(n) = 2F(n) - 1! * * Devolve: * O numero de chamadas necessaris para obter valor do elemento n * da sucessao. */ unsigned long SUCnfibonacci(int n) { int i; unsigned long fn1, fn2, fn; fn = fn1 = fn2 = 1UL; for(i = 2; i <= n; i++) { fn = 1 + fn1 + fn2; fn2 = fn1; fn1 = fn; } return fn; } /* Ou... { int i; unsigned long fn1, fn2, fn; fn = fn1 = fn2 = 1UL; for(i = 2; i <= n; i++) { fn = fn1 + fn2; fn2 = fn1; fn1 = fn; } return 2*fn-1; } */