Iteracja oraz Rekurencja

Iteracja oraz Rekurencja
P1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 27
0

Mam taki problem. Jestem początkującym w dziedzinie programowania. Otóż chciałem stworzyć program, który będzie liczył podany element ciągu. Warunki początkowe są takie:

Język to Java

a0=1;
a1=3;

ak = (ak-1)/(ak+1) dla parzystych
ak = (ak-1)*(ak+1) dla nieparzystych.

Stworzyłem kod, ale wyrzuca błąd w metodzie iteracyjnej:
Exception in thread "main" java.lang.StackOverflowError
Proszę o pomoc i poprawienie błędów z góry dziękuję!!

Mój kod:
import java.util.*;

public class Ciag {

public static int rek(int n) {
	switch (n) {
	case 0:
		return 1;
	case 1:
		return 3;

	default:
		if (n % 2 == 0) {
			return rek(n + 1) / rek(n - 1);
		} else {
			return rek(n + 1) * rek(n - 1);
		}
	}
	
}

public static int iter(int n) {
	int a0 = 1; 
	int a1 = 3; 
	int wynik = 0; 

	for (int i = 3; i <= n; i++) {
		if (n % 2 == 0) {
			wynik = a1 / a0; 
			a0 = a1;
			a1 = wynik; 
		} else {
			wynik = a1 * a0;
			a0 = a1;
			a1 = wynik; 

		}
	}
	return wynik;
}

public static void main(String[] args) {

	Scanner sc = new Scanner(System.in);
	System.out.print("Który element ciągu chcesz obliczyć: ");

	int n = sc.nextInt();

	System.out.println(n
			+ "-ty element (rekurencja) wynosi: "
			+ rek(n));
	System.out.println(n
			+ "-ty element (iteracja) wynosi: "
			+ iter(n));
}

}

  • Rejestracja: dni
  • Ostatnio: dni
0

Imo, wzory

ak = (ak-1)/(ak+1) dla parzystych
ak = (ak-1)*(ak+1) dla nieparzystych.

są bez sensu. Żeby wyliczyć wyraz o numerze k, musisz wpierw znać wyraz o numerze k+1. W rekurencji masz wtedy nieskończony ciąg wywołań.

P1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 27
0
bo napisał(a)

Imo, wzory

ak = (ak-1)/(ak+1) dla parzystych
ak = (ak-1)*(ak+1) dla nieparzystych.

są bez sensu. Żeby wyliczyć wyraz o numerze k, musisz wpierw znać wyraz o numerze k+1. W rekurencji masz wtedy nieskończony ciąg wywołań.

Poprawiłem to, rzeczywiście mój błąd, ale nadal jest źle, bo rekurencja liczy swoje, a co innego liczy iteracja. Można prosić o poprawę kodu ?

byku_guzio
  • Rejestracja: dni
  • Ostatnio: dni
0

Nic nie poprawiłeś - imho tych wzorów nie da się rozwiązać rekurencyjnie.

Na pierwszy rzut oka iteracyjny też masz źle - dzielenie przez zero. Zamiast ... n % 2 ... i % 2

Wibowit
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: XML Hills
0

W wersji iteracyjnej masz:
a_k = k % 2 == 0 ? a_{k-1} / a{k-2} : a_{k-1} * a_{k-2}

W wersji rekurencyjnej masz:
a_k = k % 2 == 0 ? a_{k+1} / a{k-1} : a_{k+1} * a_{k-1}

Przy czym tego drugiego równania nie sposób policzyć wg mnie.

P1
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 27
0

Kod po zmianach. Wersja rekurencyjna działa bez zarzutu, iteracyjna także ale dopiero od 3 elementu, bo zamiast wypisać pierwsze dwa tak jak zadeklarowałem, to ona wyrzuca w tym miejscu 0, jak to poprawić jeszcze:

import java.util.*;

public class CiagFibonacciego {

public static int rek(int n) {
	switch (n) {
	case 0:
		return 1;
	case 1:
		return 3;

	default:
		if (n % 2 == 0) {
			return rek(n - 1) / rek(n - 2);
		} else {
			return rek(n - 2) * rek(n - 1);
		}
	}
}

public static int iter(int n) {
	int a0 = 1;
	int a1 = 3;

	int wynik = 0;
	for (int i = 2; i <= n; i++) {
		if (i % 2 == 0) {
			wynik = a1 / a0;
			a0 = a1;
			a1 = wynik;
		} else {
			wynik = a1 * a0;
			a0 = a1;
			a1 = wynik;

		}
	}
	return wynik;

}

public static void main(String[] args) {

	Scanner sc = new Scanner(System.in);
	System.out.print("Który element ciągu chcesz obliczyć: ");

	int n = sc.nextInt();

	System.out.println(n + "-ty element (rekurencja) wynosi: " + rek(n));
	System.out.println(n + "-ty element (iteracja) wynosi: " + iter(n));
}

}

byku_guzio
  • Rejestracja: dni
  • Ostatnio: dni
0

przed int wynik = 0;
daj

Kopiuj
if(n == 0)
{
    return a0;
} else if(n == 1)
{
    return a1;
}

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.