コード例 #1
0
//Returns the nth term in the Fibonacci Sequence (recursive): O(2^N) [really slow]
unsigned long long recursive_fibonacci(unsigned short n)
{
    if (n == 0)
        return 0;
    if (n == 1)
        return 1;
    return recursive_fibonacci(n - 1) + recursive_fibonacci(n - 2);
}
コード例 #2
0
int main()
{
    unsigned short n = 45;
    std::cout << "Calculating fib(" << n << ") using bottom-up method: ";
    std::cout << bottom_up_fibonacci(n) << std::endl;
    std::cout << "Calculating fib(" << n << ") using recursive method: ";
    std::cout << recursive_fibonacci(n) << std::endl;
    // As you can see bottom-up it's instantanious but recursive takes some seconds to calculate fib.
}
コード例 #3
0
ファイル: fibonacci.c プロジェクト: MMSequeira/eda
// ### Programa principal
int main(void)
{
	// Definimos uma constante que guarda o número do maior termo da
	// sucessão de Fibonacci que será usado nas experiências realizadas com
	// a função que usa o algoritmo recursivo estúpido. Sem este cuidado, o
	// nosso programa não terminaria em tempo útil.
	const int last_term_to_test_with_stupid_algorithm = 42;

	// Realizamos experiências com cada uma das funções, para obter
	// estimativas do seu tempo de execução.
	experiment_efficiency_of(
		"Stupidly recursive implementation of the fibonacci sequence:",
		stupidly_recursive_fibonacci,
		last_term_to_test_with_stupid_algorithm);
	experiment_efficiency_of(
		"Recursive implementation of the fibonacci sequence using array"
		" for storage:",
		recursive_fibonacci, MAXIMUM_TERM_FITTING_A_LONG);
	experiment_efficiency_of(
		"Recursive implementation of the fibonacci sequence using ADT"
		" for storage:",
		recursive_fibonacci_using_ADT, MAXIMUM_TERM_FITTING_A_LONG);
	experiment_efficiency_of(
		"Tail recursive implementation of the fibonacci sequence:",
		iterative_fibonacci, MAXIMUM_TERM_FITTING_A_LONG);
	experiment_efficiency_of(
		"Two variable iterative implementation of the fibonacci"
		" sequence:",
		iterative_fibonacci, MAXIMUM_TERM_FITTING_A_LONG);

	// Finalmente, usamos cada uma das funções para obter os termos da
	// sucessão, podendo assim mais facilmente confirmar que os cálculos
	// estão a ser realizados correctamente.
	for (int n = 0; n != MAXIMUM_TERM_FITTING_A_LONG + 1; n++) {
		if (n <= last_term_to_test_with_stupid_algorithm)
			printf("F(%d) [stupidly recursive] = %ld\n",
				n, stupidly_recursive_fibonacci(n));
		printf("F(%d) [recursive         ] = %ld\n",
			n, recursive_fibonacci(n));
		printf("F(%d) [recursive with ADT] = %ld\n",
			n, recursive_fibonacci_using_ADT(n));
		printf("F(%d) [tail recursive    ] = %ld\n",
			n, tail_recursive_fibonacci(n));
		printf("F(%d) [iterative         ] = %ld\n",
			n, iterative_fibonacci(n));
		putchar('\n');
	}

	return EXIT_SUCCESS;
}
コード例 #4
0
ファイル: fibonacci.c プロジェクト: MMSequeira/eda
// #### Definição
long recursive_fibonacci(int n)
{
	assert(n >= 0);
	assert(n <= MAXIMUM_TERM_FITTING_A_LONG);

	// Esta implementação evita os cálculos repetidos dos mesmos termos da
	// sucessão de Fibonacci usando uma memória auxiliar. A ideia é calcular
	// cada termo da sucessão uma única vez, guardar o seu valor em memória
	// e, das próximas vezes que o termo for solicitado, usar o valor
	// guardado em memória. Isto implica, naturalmente, que a memória usada
	// persista para além do âmbito restrito de uma execução da função. Ou
	// seja, não podemos de forma nenhuma usar variáveis locais
	// _automáticas_, pois estas são construídas quando a instrução que as
	// define é executada, e destruídas quando se atinge o final do bloco
	// onde a sua definição se encontra. Em vez de partir daqui para as
	// variáveis globais, cujo tempo de vida abarca todo o tempo de execução
	// do programa, e que são visíveis em todo o programa, preferimos usar
	// variáveis locais _estáticas_. Estas variáveis definem-se usando o
	// _qualificador_ `static`, duram desde a execução da instrução que as
	// define até o final do programa e têm a mesma visibilidade restrita
	// que qualquer variável local tem. Note-se que a instrução de definição
	// de qualquer variável local estática é executada uma única vez,
	// nomeadamente a primeira vez que o fluxo de execução do programa passa
	// por essa instrução. A partir daí a instrução de definição, com a
	// respectiva inicialização, é ignorada. Logo, a inicialização de uma
	// variável local estática _é feita uma única vez_ durante a execução do
	// programa.
	//
	// Uma vez que o número de termos da sucessão de Fibonacci calculáveis
	// através desta função é limitado, dado que ela devolve valores `long`,
	// só se podendo calcular o valor dos termos entre 0 e
	// `MAXIMUM_TERM_FITTING_A_LONG`, podemos reservar espaço para todos os
	// termos num _array_ `F` de `long`. A utilização de uma macro
	// `MAXIMUM_TERM_FITTING_A_LONG` na expressão para cálculo do
	// comprimento do _array_ permite-nos usar inicializadores do C. Dessa
	// forma, podemos inicializar a memória dos termos da sucessão de
	// Fibonacci com os dois primeiros termos dessa sucessão, que têm os
	// valores 0 e 1, respectivamente, correspondentes aos termos com
	// índices 0 e 1.
	static long F[MAXIMUM_TERM_FITTING_A_LONG + 1] = {0, 1};
	// Não basta definir o espaço de memória dos termos da sucessão: é
	// necessário definir uma variável que guarde em cada instante quantos
	// termos estão já calculados. Neste caso inicializa-se a variável com o
	// valor 2, uma vez que se inicializou a memória com os dois primeiros
	// termos da sucessão de Fibonacci.
	static int number_of_calculated_terms = 2;

	// Estamos agora preparados para indagar o valor do termo da sucessão de
	// Fibonacci solicitado. Se o termo já constar na memória de termos
	// calculados, i.e., se o valor `n` for inferior a
	// `number_of_calculated_terms` limitamo-nos a devolver o valor
	// memorizado.
	if (n < number_of_calculated_terms)
		return F[n];

	// O caso geral passa por
	//
	// 1. invocar recursivamente a própria função para obter os termos `n -
	// 2` e `n - 1`,
	//
	// 2. calcular o termo `n` como soma dos dois termos anteriores
	// calculados,
	//
	// 3. guardar esse novo termo na memória, de modo a não precisar de ser
	// recalculado, e
	//
	// 4. terminar a função, devolvendo o valor do novo termo ao retornar ao
	// ponto de invocação da função.
	//
	// Estes passos estão condensados em apenas duas linhas de código. Essa
	// condensação seria considerada uma má prática em quase todas as
	// linguagens de programação, mas este tipo de código é idiomático em C,
	// pelo que preferimos apresentá-lo desta forma. Seja como for, uma
	// forma ortodoxa de escrever este código seria:
	//
	// ```C
	// F[n] = recursive_fibonacci(n - 2) + recursive_fibonacci(n - 1);
	// number_of_calculated_terms++;
	//
	// return F[n];
	// ```
	//
	// Alternativamente, podemos considerar que o caso especial é aquele em
	// que o termo pretendido _não_ foi ainda calculado, o que nos levaria
	// ao seguinte código, bem mais legível, que substitui não apenas as
	// duas últimas linhas do código apresentado, mas também as duas
	// anteriores:
	//
	// ```C
	// if (number_of_calculated_terms <= n) {
	//         F[n] = recursive_fibonacci(n - 2) +
	//                recursive_fibonacci(n - 1);
	//         number_of_calculated_terms++;
	// }
	//
	// return F[n];
	// ```
	number_of_calculated_terms++;
	return F[n] = recursive_fibonacci(n - 2) + recursive_fibonacci(n - 1);
}