Boa noite…
Qual a vantagem de usar a recursividade no java?
Eu to tentando aprender mas eu acho os metodos nao recursivos mais faceis de usar…
Olá amigo, a recursividade é um pouco complexa inicialmente,mas com tempo e pratica vai aparecendo certa situações que é necessária, a vantagem depende do algoritmo que está sendo desenvolvido, quando você está fazendo estrutura de dados(fila, pilha, lista encadeada e etc) na maioria dos casos utilizar a recursividade para deixar o código mais enxuto , legível e evitar muitos laço de repetição.
Independente da linguagem, recursividade pode ser útil em diversos cenários.
Acredito que sua maior vantagem é o fato de que o empilhamento das chamadas de métodos é gerenciado pelo sistema operacional (ou pela máquina virtual no caso do Java) poupando assim o programador de implementar uma estrutura de pilha.
Vou te dar um desafio simples:
Escreva um algoritmo que liste todos os arquivos de todas as pastas e subpastas de uma unidade de disco de seu computador.
Tente implementar uma versão sem recursividade e outra com recursividade.
Passei um tempo estudando algoritmos recursivos e percebi que são mais fáceis de implementar do que os iterativos.
Os recursivos são mais difíceis de visualizar e as vezes mais difíceis de entender oque o algoritmo faz, mas percebi que muitos deles seguem um certo padrão:
Number método(Parâmetros) {
// bloco de calculo de condição de saída
// bloco de condição de saída
// bloco de calculo de bloco de repetição
// bloco de repetição
}
Exemplo Fibonacci:
int Fibonacci(int numero) {
// bloco de calculo de condição de saída
// nada
// bloco de condição de saída
if (numero == 0) return 0;
if (numero == 1) return 1;
// bloco de calculo de bloco de repetição
// nada
// bloco de repetição
return Fibonacci(numero - 1) + Fibonacci(numero - 2);
}
Exemplo do algoritmo listar arquivos do @staroski :
void listarArquivos(Pasta pasta, Lista arquivos) {
// bloco de calculo de condição de saída
// nada
// bloco de condição de saída
// nada
// bloco de calculo de bloco de repetição
Lista pastas;
for (item : pasta) {
if (item é arquivo) {
arquivos.add(item);
} else if (item é pasta) {
pastas.add(item);
}
}
// bloco de repetição
for (item : pastas) {
listarArquivos(item, arquivos);
}
}
ou
void listarArquivos(Item item, Lista arquivos) {
// bloco de calculo de condição de saída
// nada
// bloco de condição de saída
if (item é arquivo) {
arquivos.add(item);
return;
} // else item é pasta
// bloco de calculo de bloco de repetição
// nada
// bloco de repetição
for (i : item) {
listarArquivos(i, arquivos);
}
}
Compreendi a diferença…entretanto to achando muito dificil aprender…ja vi varios videos… mas nao aprendi de fato.
Tem algum site que ensine a fundo este assunto?
No início é confuso, mas a recursividade é basicamente um método que chama a si mesmo.
Ele trabalha de forma semelhante ao while, onde é necessário saber em que ponto o laço é quebrado.
No geral, é observar o comportamento e praticar.
Veja um exemplo, onde a codificação se comporta como se tive-se um while.
import java.util.Scanner;
public class Teste {
public static void main(String[] args) {
new Teste().escrevaAlgo(new Scanner(System.in));
}
private void escrevaAlgo(Scanner scan) {
System.out.println(scan.hashCode()+" Informe algo:");
String entrada = scan.nextLine();
switch (entrada.toLowerCase()) {
case "sair":
System.out.println("Saindo da aplicação");
break;
default:
System.out.println("Entrada informada: " + entrada+"\n");
escrevaAlgo(scan);//como não digitou sair, o método chamou a si mesmo
}
System.out.println("Té+");//o comportamento aqui será "acumulado"
scan.close();
}
}
Então, recursividade é bem legal, mas deve ser usada com cuidado pois consome muito recurso e possui construções diferentes, ou seja depende da finalidade.
Na construção acima, eu não retornei nada, apenas chamei o método, este é um comportamento básico.
Seria possível chamar este método indiretamente, mas ai já é outra situação.
Resumo, praticar.
faça uma funçao recursiva que calcula a quantidade de caracteres em uma string.
Fiz da seguinte forma e funcionou:
public static int contarCaracteres(String str){
if ( str.length()==0)
{
return 0;
}
if (str.length()==1){
return 1;
}
str = str.substring(1, str.length());
return 1 + contarCaracteres(str);
}
Agora é praticar, lembrando que a recursividade deve ser usada com cuidado.
Fazer uma funçao recursiva que calcule o valor da serie S descrita a seguir para um valor n>0 a ser fornecido como parametro para a mesma: S= 1 + 1/2! + 1/3! + … 1/n!
Aqui fiz da seguinte forma… eu coloquei uma funca dentro de outra funçao… Eu ja tinha uma funçao que calculava o fatorial
public static int calcular(int num){
if (num == 0){
return 1;
} else {
return num * calcular(num-1);
}
}
public static double serie(int num){
if (num==0){
return 0;
}
if (num==1){
return 1;
}
return 1/ (calcular(num)) + serie(num-1);
}
Esta certo?