[resolvido] Como vcs fariam?

5 respostas
LeandroSantanaDiniz

Oi, boa noite …

Eu resolvi este exercício da apostila da Caelum:


  1. No capítulo anterior, você deve ter reparado que a versão recursiva para o problema de Fibonacci é lenta
    porque toda hora estamos recalculando valores. Faça com que a versão recursiva seja tão boa quanto a
    versão iterativa. (Dica: use arrays para isso)

página 56


Ficou desta forma:

Fibonacci.java

public class Fibonacci
{
	int[] array = new int[2000];
	int fibonacci = 50;
	
	int calculaFibonacci()
	{
		
		--this.fibonacci;
		int loop = 0;

		if (this.fibonacci >= 0)
		{			
				for(loop = 0 ; loop <= this.fibonacci ; loop++)
				{
					if(loop == 0)
					{
						this.array[loop] = 1;
					
					}else if(loop == 1)
							{
								this.array[loop] = 1;
							}else
								{
									this.array[loop] = this.array[loop-1] + this.array[loop-2];	
								}
				}
			
		}
		
		return this.array[--loop];
	}
}

e o Teste … FibonacciTeste.java

public class TesteFibonacci
{
	public static void main(String[] args)
	{
		Fibonacci xicara = new Fibonacci();
		
		int valor = xicara.calculaFibonacci();
		
		System.out.println("Tcharam: " + valor);
		
	}
}

Porém estou achando que gastei muitas linhas, como vcs fariam ? deem uma opiniao, por favor…

5 Respostas

JuniorMaia
System.out.println("Tcharam: " + valor);

“Tcharam” kkkkkkkkkkkkkkkkkkkkkkkkkkk ;x

LeandroSantanaDiniz

JuniorMaia:
System.out.println("Tcharam: " + valor);

“Tcharam” kkkkkkkkkkkkkkkkkkkkkkkkkkk ;x

AWUHIUSHUIWHOAHSUAHOUIAW

ViniGodoy

Da forma que você fez, não é recursiva. Lembre-se, uma função recursiva é aquela que chama a si mesmo. [E o caso da função de Fibonacci, que pode ser calculada assim:
[img]http://upload.wikimedia.org/wikipedia/pt/math/0/d/5/0d5cce25d67941bb4661afd52609d93c.png[/img]

O segredo está em perceber que quando você calcula um número, como o fibonacci de 6, você calcula:
[img]http://www.cs.ucc.ie/~dongen/mpost/jpg/FibonacciTree0.jpg[/img]

Note que o fib(4) teve que ser calculado 2 vezes (para o resultado de fib(6) e de fib(5)). O mesmo vale para o fib(3), que teve que ser calculado 3 vezes. E é justamente o fato de calcular várias vezes a mesma coisa que torna tudo tão ineficiente (alguns números chegam a ser calculados dezenas de vezes).

O que você tem que fazer, então, é guardar os valores já calculados no array. Só recalcule-os se não estiverem calculados.

public class Fibonacci 
{
    private long[] valores = new long[2000];

    public Fibonacci() {
        valores[1] = 1;
    }

    public long calcula(int n) {
        if (n == 0) return 0;

        //Retornamos valores  calculados diretamente
        if (valores[n] != 0) return valores[n];

        //Caso contrário, calculamos e guardamos o valor calculado
        valores[n] = calcula(n-1) + calcula(n-2);

        return valores[n]; //Retornamos o valor calculado
    }
}
No main, rode com:
System.out.println("Tcharam: " + new Fibonacci().calcula(50));

A técnica de guardar valores pré-calculados na memória chama-se cache.
Esse programa pode ser mais rápido, mas ocupa muito mais memória que o anterior.

Quanto falamos em performance, sempre temos que lidar com o trade-off de processador vs. memória.

LeandroSantanaDiniz
ViniGodoy:
Da forma que você fez, não é recursiva. Lembre-se, uma função recursiva é aquela que chama a si mesmo. [E o caso da função de Fibonacci, que pode ser calculada assim: [img]http://upload.wikimedia.org/wikipedia/pt/math/0/d/5/0d5cce25d67941bb4661afd52609d93c.png[/img]

O segredo está em perceber que quando você calcula um número, como o fibonacci de 6, você calcula:
[img]http://www.cs.ucc.ie/~dongen/mpost/jpg/FibonacciTree0.jpg[/img]

Note que o fib(4) teve que ser calculado 2 vezes (para o resultado de fib(6) e de fib(5)). O mesmo vale para o fib(3), que teve que ser calculado 3 vezes. E é justamente o fato de calcular várias vezes a mesma coisa que torna tudo tão ineficiente (alguns números chegam a ser calculados dezenas de vezes).

O que você tem que fazer, então, é guardar os valores já calculados no array. Só recalcule-os se não estiverem calculados.

public class Fibonacci 
{
    private long[] valores = new long[2000];

    public Fibonacci() {
        valores[1] = 1;
    }

    public long calcula(int n) {
        if (n == 0) return 0;

        //Retornamos valores  calculados diretamente
        if (valores[n] != 0) return valores[n];

        //Caso contrário, calculamos e guardamos o valor calculado
        valores[n] = calcula(n-1) + calcula(n-2);

        return valores[n]; //Retornamos o valor calculado
    }
}
No main, rode com:
System.out.println("Tcharam: " + new Fibonacci().calcula(50));

A técnica de guardar valores pré-calculados na memória chama-se cache.
Esse programa pode ser mais rápido, mas ocupa muito mais memória que o anterior.

Quanto falamos em performance, sempre temos que lidar com o trade-off de processador vs. memória.

brigado, se vc tiver algum exercicio parecido com esse me fale, por favor...

Rocklee6544

Tente fazer fatorial, é clássico pedirem isso.
Na faculdade e as vezes até em entrevista.
Essa do fibonacci do vini foi massa.
mlk zica.

O único que melhorei foi o do método bolha.
Esse do fibonacci sempre fiz da maneira clássica e burra.

A complexidade desse algoritmo é de ordem n², gostaria de saber como ficaria a pilha em um fibonacci.

fatorial de 5 a pilha ficaria nessa ordem.

:1:

::2::
:::3:::
::::4::::
:::::5::::: em um algoritmo como esse literalmente se chega ao topo e depois vc volta multiplicando.(e todos tem critério de parada, nesse caso zero).

Estava pensando como seria a pilha do fibonacci , mas é como o vini fez uma árvore.

Criado 2 de junho de 2012
Ultima resposta 6 de jun. de 2012
Respostas 5
Participantes 4