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에서 첫 번째 n 피보나치 수 얻기
처음 n개의 피보나치 수를 얻는 작업이 있다고 가정합니다.-
사례 0.1:
특정 숫자 n이 우리에게 옵니다.
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]; }
n 크기의 배열을 만듭니다. 처음 두 요소는 0과 1과 같으며 나머지 요소는 이 루프를 통과하고 배열의 이전 숫자를 사용하여 얻습니다.
그리고 우리는 다음을 표시합니다:
for (int i = 0; i < arr.length; ++i) { System.out.println(arr[i]); }
int n = 10으로 설정합니다.
그리고 우리는 다음을 얻습니다:
0 1 1 2 3 5 8 13 21 34
-
사례 1.1의 경우 솔루션은 실제로 다르지 않습니다.
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] 배열의 첫 번째 요소(0에서 1)뿐이었습니다. 따라서 처음 10개 요소는 다음과 같습니다.
1 1 2 3 5 8 13 21 34 55
스트림을 통한 첫 번째 n 피보나치 수
하지만 우리는 우리의 수준을 보여주고 싶습니다. 이제 stream 을 사용하여 이 솔루션이 어떤 모습인지 살펴보겠습니다 .-
0.1의 경우:
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 클래스 의 정적 반복 메서드는 초기 배열 arr에 함수를 적용하여 생성된 무한 순서 스트림을 반환합니다. 우리의 경우 함수는 이전 배열을 기반으로 각각의 새 배열을 구성하는 규칙을 설정하는 것입니다. 결과적으로 우리는 배열 스트림을 얻게 됩니다:
{0,1} {1,1} {1, 2} {2, 3} {3, 5} {5, 8} {8, 13} {13, 21} {21, 34} {34, 55} …..
그러나 그 수는 무한하므로 .limit(n)을 사용하여 요소 수를 처음 n(이 경우 10)으로 줄입니다.
그러나 배열 스트림은 필요하지 않으므로 .map(y -> y[0])을 사용하여 각 배열의 첫 번째 요소를 선택하고 필요한 숫자가 포함된 스트림을 얻은 다음 forEach를 사용하여 콘솔에 인쇄합니다. .
더 시원해 보이지 않나요?
첫 번째 요소가 1,1인 경우 이 코드도 거의 동일합니다.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));
다시 말하지만 차이점은 초기 요소에 있습니다. {0, 1} 대신 {1, 1}을 설정합니다.
실제로 결과는 이전 예와 동일합니다.
피보나치 수열의 합
n번째 요소까지의 피보나치 수의 합을 구하라는 요청을 받으면 어떻게 될까요? 이것이 우리에게 어떤 어려움도 야기해서는 안 됩니다. 스트림을 사용하여 솔루션을 취하고 forEach를 몇 가지 다른 방법으로 대체해 보겠습니다.-
0.1의 경우:
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)를 사용하여 스트림을 숫자 IntStream으로 변환하고 해당 .sum() 메서드를 사용하여 모든 요소의 합계를 얻습니다.
- 1,1 초기 요소가 있는 경우에는 {0, 1} 대신 {1, 1}을 설정합니다.
피보나치 수열의 n번째 숫자 얻기
때때로 일련의 숫자가 아니라 특히 피보나치 수열의 n번째 숫자를 인쇄하라는 요청을 받습니다. 일반적으로 이전 솔루션을 쉽게 적용할 수 있으므로 작업이 더 쉬워집니다. 그렇다면 재귀를 통해 문제를 해결해 보는 것은 어떨까요?-
0.1의 경우:
public int getFibonacciValue(int n) { if (n <= 1) { return 0; } else if (n == 2) { return 1; } else { return getFibonacciValue(n - 1) + getFibonacciValue(n - 2); } }
0,1로 알고리즘을 실행하려면 첫 번째 요소를 얻으려고 할 때 0을 얻고 두 번째 요소는 - 1을 얻도록 지정해야 합니다. 실제로 이전 솔루션에서와 마찬가지로 처음 두 요소를 설정해야 합니다. 강요.
-
1.1의 구현은 약간 다릅니다.
public int getFibonacciValue(int n) { if (n == 0) { return 0; } else if (n == 1) { return 1; } else { return getFibonacciValue(n - 1) + getFibonacciValue(n - 2); } }
이 경우 두 번째 요소는 동일하고 메서드의 응답도 동일하므로 첫 번째 요소만 1로 설정하면 됩니다.
동시에 메소드의 반응을 0으로 설정합니다. 설정하지 않으면 2가 인수로 올 때 동일한 메소드가 재귀적으로 호출되지만 인수는 0입니다. 다음으로 동일한 메소드가 실행됩니다. , 그러나 음수 등은 음의 무한대까지 계속됩니다. 결과적으로 StackOverflowError 가 발생합니다 .
GO TO FULL VERSION