TheAlgorithms-Python
132 строки · 2.9 Кб
1"""
2This is pure Python implementation of fibonacci search.
3
4Resources used:
5https://en.wikipedia.org/wiki/Fibonacci_search_technique
6
7For doctests run following command:
8python3 -m doctest -v fibonacci_search.py
9
10For manual testing run:
11python3 fibonacci_search.py
12"""
13
14from functools import lru_cache15
16
17@lru_cache
18def fibonacci(k: int) -> int:19"""Finds fibonacci number in index k.20
21Parameters
22----------
23k :
24Index of fibonacci.
25
26Returns
27-------
28int
29Fibonacci number in position k.
30
31>>> fibonacci(0)
320
33>>> fibonacci(2)
341
35>>> fibonacci(5)
365
37>>> fibonacci(15)
38610
39>>> fibonacci('a')
40Traceback (most recent call last):
41TypeError: k must be an integer.
42>>> fibonacci(-5)
43Traceback (most recent call last):
44ValueError: k integer must be greater or equal to zero.
45"""
46if not isinstance(k, int):47raise TypeError("k must be an integer.")48if k < 0:49raise ValueError("k integer must be greater or equal to zero.")50if k == 0:51return 052elif k == 1:53return 154else:55return fibonacci(k - 1) + fibonacci(k - 2)56
57
58def fibonacci_search(arr: list, val: int) -> int:59"""A pure Python implementation of a fibonacci search algorithm.60
61Parameters
62----------
63arr
64List of sorted elements.
65val
66Element to search in list.
67
68Returns
69-------
70int
71The index of the element in the array.
72-1 if the element is not found.
73
74>>> fibonacci_search([4, 5, 6, 7], 4)
750
76>>> fibonacci_search([4, 5, 6, 7], -10)
77-1
78>>> fibonacci_search([-18, 2], -18)
790
80>>> fibonacci_search([5], 5)
810
82>>> fibonacci_search(['a', 'c', 'd'], 'c')
831
84>>> fibonacci_search(['a', 'c', 'd'], 'f')
85-1
86>>> fibonacci_search([], 1)
87-1
88>>> fibonacci_search([.1, .4 , 7], .4)
891
90>>> fibonacci_search([], 9)
91-1
92>>> fibonacci_search(list(range(100)), 63)
9363
94>>> fibonacci_search(list(range(100)), 99)
9599
96>>> fibonacci_search(list(range(-100, 100, 3)), -97)
971
98>>> fibonacci_search(list(range(-100, 100, 3)), 0)
99-1
100>>> fibonacci_search(list(range(-100, 100, 5)), 0)
10120
102>>> fibonacci_search(list(range(-100, 100, 5)), 95)
10339
104"""
105len_list = len(arr)106# Find m such that F_m >= n where F_i is the i_th fibonacci number.107i = 0108while True:109if fibonacci(i) >= len_list:110fibb_k = i111break112i += 1113offset = 0114while fibb_k > 0:115index_k = min(116offset + fibonacci(fibb_k - 1), len_list - 1117) # Prevent out of range118item_k_1 = arr[index_k]119if item_k_1 == val:120return index_k121elif val < item_k_1:122fibb_k -= 1123elif val > item_k_1:124offset += fibonacci(fibb_k - 1)125fibb_k -= 2126return -1127
128
129if __name__ == "__main__":130import doctest131
132doctest.testmod()133