F = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, ...}
F 0 = 0, F 1 = 1, F n = F n - 1 + F n - 2 ;
n ≥ 0, n ∈ Z
Java-da birinchi n Fibonachchi raqamlarini olish
Faraz qilaylik, bizda birinchi n Fibonachchi raqamini olish vazifasi bor.-
0.1 holat:
Bizga ma'lum bir n raqami keladi:
int[] arr = new int[n]; arr[0] = 0; arr[1] = 1; for (int i = 2; i < arr.length; ++i) { arr[i] = arr[i - 1] + arr[i - 2]; }
Biz n o'lchamli massivni yaratamiz. Birinchi ikkita element nolga va bittaga teng bo'ladi, qolgan elementlar esa ushbu tsikldan o'tib, massivdagi oldingi raqamlardan foydalangan holda olinadi.
Va biz ko'rsatamiz:
for (int i = 0; i < arr.length; ++i) { System.out.println(arr[i]); }
int n = 10 ni o'rnating;
Va biz olamiz:
0 1 1 2 3 5 8 13 21 34
-
1.1-holat uchun yechim aslida farq qilmaydi:
int[] arr = new int[n]; arr[0] = 1; arr[1] = 1; for (int i = 2; i < arr.length; ++i) { arr[i] = arr[i - 1] + arr[i - 2]; }
arr[0] massivning birinchi elementini o‘zgartirishimiz kerak edi: 0 dan 1 gacha. Shunga ko‘ra, dastlabki 10 ta element quyidagilar bo‘ladi:
1 1 2 3 5 8 13 21 34 55
Oqim orqali birinchi n Fibonachchi raqamlari
Lekin biz o'z darajamizni ko'rsatmoqchimiz. Keling, ushbu yechim stream yordamida qanday ko'rinishini ko'rib chiqaylik .-
0,1 uchun:
Stream.iterate(new int[]{0, 1}, arr -> new int[]{arr[1], arr[0]+ arr[1]}) .limit(n) .map(y -> y[0]) .forEach(x -> System.out.println(x));
Stream sinfining statik takrorlash usuli funktsiyani boshlang'ich massivga qo'llash orqali yaratilgan cheksiz tartiblangan oqimni qaytaradi. Bizning holatda, funktsiya avvalgisiga asoslanib, har bir yangi massivni tuzish qoidasini o'rnatishdan iborat. Natijada biz massivlar oqimini olamiz:
{0,1} {1,1} {1, 2} {2, 3} {3, 5} {5, 8} {8, 13} {13, 21} {21, 34} {34, 55} …..
Lekin ularning soni cheksiz bo'ladi va shuning uchun .limit(n) dan foydalanib biz elementlar sonini birinchi n gacha (bizning holimizda 10 tagacha) kamaytiramiz.
Biroq, bizga massivlar oqimi kerak emas, shuning uchun .map(y -> y[0]) yordamida biz har bir massivning birinchi elementini tanlaymiz va kerakli raqamlar bilan oqim olamiz va forEach yordamida konsolga chop etamiz. .
Salqinroq ko'rinadi, shunday emasmi?
birinchi elementlar 1,1 bo'lsa, bu kod ham deyarli bir xil bo'ladi:Stream.iterate(new int[]{1, 1}, arr -> new int[]{arr[1], arr[0]+ arr[1]}) .limit(n) .map(y -> y[0]) .forEach(x -> System.out.println(x));
Shunga qaramay, farqlar boshlang'ich elementda: {0, 1} o'rniga biz {1, 1} ni o'rnatamiz.
Aslida, natijalar avvalgi misoldagi kabi bo'ladi.
Fibonachchi raqamlari yig'indisi
Agar bizdan Fibonachchi raqamlari yig'indisini n-chi elementgacha olish so'ralsa-chi? Bu bizga hech qanday qiyinchilik tug'dirmasligi kerak. Keling, oqim bilan yechimni olamiz va forEach ni bir nechta boshqa usullar bilan almashtiramiz:-
0,1 uchun:
int n = 10; int result = Stream.iterate(new int[]{0, 1}, arr -> new int[]{arr[1], arr[0]+ arr[1]}) .limit(n) .map(t -> t[0]) .mapToInt(Integer::intValue) .sum(); System.out.println(result);
.mapToInt(Integer::intValue) yordamida biz oqimimizni raqamli IntStreamga aylantiramiz va barcha elementlarning yig'indisini olish uchun uning .sum() usulidan foydalanamiz.
- 1,1 boshlang'ich elementli holat uchun {0, 1} o'rniga {1, 1} ni o'rnatamiz.
Fibonachchi qatoridagi n-sonni olish
Ba'zan sizdan raqamlar qatorini emas, balki Fibonachchi seriyasidagi n-sonni chop etishingiz so'raladi. Qoida tariqasida, bu faqat vazifani osonlashtiradi, chunki siz buning uchun oldingi echimlarni osongina moslashingiz mumkin. Xo'sh, muammoni rekursiya orqali hal qilish haqida nima deyish mumkin?-
0,1 uchun:
public int getFibonacciValue(int n) { if (n <= 1) { return 0; } else if (n == 2) { return 1; } else { return getFibonacciValue(n - 1) + getFibonacciValue(n - 2); } }
Algoritmni 0,1 bilan ishga tushirish uchun birinchi elementni olishga harakat qilganimizda biz 0 ni, ikkinchisini esa 1 ga olishini aniqlab olishimiz kerak.Aslida biz avvalgi yechimlarda bo'lgani kabi birinchi ikkitasini o'rnatishimiz kerak. elementlar.
-
1.1 uchun amalga oshirish biroz boshqacha bo'ladi:
public int getFibonacciValue(int n) { if (n == 0) { return 0; } else if (n == 1) { return 1; } else { return getFibonacciValue(n - 1) + getFibonacciValue(n - 2); } }
Bunday holda, biz faqat birinchi elementni 1 deb belgilashimiz kerak, chunki ikkinchi element bir xil bo'ladi va usulning javobi bir xil bo'ladi.
Shu bilan birga, biz usulning reaktsiyasini 0 ga qo'yamiz, chunki agar biz uni qo'ymasak, argument sifatida 2 kelganda, xuddi shu usul rekursiv chaqiriladi, lekin argument 0 bilan. Keyin xuddi shu usul ishga tushiriladi. , lekin manfiy sonlar bilan va manfiy cheksizgacha davom etadi. Natijada biz StackOverflowError ni olamiz .
GO TO FULL VERSION