어떻게 Python을 이용하여 이분 찾기를 실현합니까 (교체 및 귀속)
17603 단어 돌아오지 않는 파이썬
2분 Binary 검색
알고리즘 사상: 2분 찾기는 n개의 요소를 포함하는 질서정연한 서열에서 목표 값을 효과적으로 포지셔닝하는 데 사용된다.세 가지 상황을 고려해 보자.
value == [middle]
의 데이터가 성공적으로 검색되고 종료된 경우value > [middle]
의 데이터가 후반부 서열에 대해 이 과정을 반복한다면 인덱스의 범위는 mid + 1
부터 right
까지value < [middle]
의 데이터가 앞부분 서열에 대해 이 과정을 반복한다면 인덱스의 범위는 left
부터 middle - 1
까지반복 정의 - Iteratively # binary_search.py
def binary_search_iterative(elements, value):
left, right = 0, len(elements)-1
while left <= right:
middle = (left + right) // 2
if elements[middle] == value:
return middle
elif elements[middle] < value:
left = middle + 1
else:
right = middle - 1
return None
if __name__ == '__main__':
nums = [1, 2, 3, 4, 5]
print(binary_search_iterative(nums, 2)) # Output: 1, 2 1 ( 0 )
print(binary_search_iterative(nums, 10)) # Output: None, ,
반복 정의 - Recursively
제1판
슬라이스 연산자 :
를 사용하여 목록을 잘라냅니다.def binary_search_recursive(elements, value):
if len(elements) == 0:
return False
left, right = 0, len(elements) - 1
if left <= right:
middle = (left + right) // 2
if elements[middle] == value:
return True
elif elements[middle] < value:
return binary_search_recursive(elements[middle+1:], value)
else:
return binary_search_recursive(elements[:middle], value)
return False
if __name__ == '__main__':
nums = [1, 2, 3, 4, 5]
print(binary_search_recursive(nums, 2)) # True
print(binary_search_recursive(nums, 10)) # False
반복처럼 while
순환을 사용하지 않고 조건을 검사하기만 하면 된다.대응하는 분할 목록에서 같은 함수를 호출합니다.
분할 필름을 사용하면 어떤 문제가 있습니까?알겠습니다. 슬라이스는 원소가 인용하는 복사본을 생성합니다. 이 복사본들은 현저한 메모리와 계산 비용을 가지고 있을 수 있습니다.
제2판
복사 작업을 피하기 위해 같은 목록을 반복해서 사용할 수 있지만 필요할 때 함수에 다른 경계를 전달할 수 있습니다.def binary_search(elements, value, left, right):
if left <= right:
middle = (left + right) // 2
if elements[middle] == value:
return True
elif elements[middle] < value:
return binary_search(elements, value, middle+1, right)
else:
return binary_search(elements, value, left, middle-1)
return False
if __name__ == '__main__':
nums = [1, 2, 3, 4, 5]
print(binary_search(nums, 2, 0, len(nums)-1)) # True
print(binary_search(nums, 10, 0, len(nums)-1)) # False
단점은 이 함수를 호출할 때마다 초기 경계를 전달해야 합니다. binary_search(nums, 10, 0, len(nums)-1)
제3판
더 나아가 함수를 다른 함수에 중첩하여 기술적 세부 사항을 숨기고 외부 역할 영역에서 변수를 다시 사용하고자 할 수도 있습니다.def contains(elements, value):
def recursive(left, right):
if left <= right:
midddle = (left + right) // 2
if elements[midddle] == value:
return True
elif elements[midddle] < value:
return recursive(midddle+1, right)
else:
return recursive(left, midddle-1)
return False
return recursive(0, len(elements) - 1)
if __name__ == '__main__':
nums = [1, 2, 3, 4, 5]
print(contains(nums, 2)) # True
print(contains(nums, 10)) # False
폐쇄된 범위 내에서 recursive()
내부 함수를 정의한 경우에도 요소와 값 매개 변수에 접근할 수 있습니다.
교체와 귀속 실현 사이의 선택은 일반적으로 성능 고려, 편의성, 그리고 개인의 취향의 최종 결과이다.
총결산
본고는 먼저 2분 찾기의 기본 사상을 소개한 다음에 교체와 귀속 두 가지 방법으로 간이판의 2분 찾기를 실현했다. 사실 Python은 기능이 더욱 강한 2분 찾기 라이브러리bisect
를 실현했고 흥미를 가진 학생들은 본고를 바탕으로 학습할 수 있다.
마지막: 2분 검색 시간 복잡도: O(log(n))
추천 읽기: How to Do a Binary 검색 in Python
# binary_search.py
def binary_search_iterative(elements, value):
left, right = 0, len(elements)-1
while left <= right:
middle = (left + right) // 2
if elements[middle] == value:
return middle
elif elements[middle] < value:
left = middle + 1
else:
right = middle - 1
return None
if __name__ == '__main__':
nums = [1, 2, 3, 4, 5]
print(binary_search_iterative(nums, 2)) # Output: 1, 2 1 ( 0 )
print(binary_search_iterative(nums, 10)) # Output: None, ,
제1판
슬라이스 연산자
:
를 사용하여 목록을 잘라냅니다.def binary_search_recursive(elements, value):
if len(elements) == 0:
return False
left, right = 0, len(elements) - 1
if left <= right:
middle = (left + right) // 2
if elements[middle] == value:
return True
elif elements[middle] < value:
return binary_search_recursive(elements[middle+1:], value)
else:
return binary_search_recursive(elements[:middle], value)
return False
if __name__ == '__main__':
nums = [1, 2, 3, 4, 5]
print(binary_search_recursive(nums, 2)) # True
print(binary_search_recursive(nums, 10)) # False
반복처럼
while
순환을 사용하지 않고 조건을 검사하기만 하면 된다.대응하는 분할 목록에서 같은 함수를 호출합니다.분할 필름을 사용하면 어떤 문제가 있습니까?알겠습니다. 슬라이스는 원소가 인용하는 복사본을 생성합니다. 이 복사본들은 현저한 메모리와 계산 비용을 가지고 있을 수 있습니다.
제2판
복사 작업을 피하기 위해 같은 목록을 반복해서 사용할 수 있지만 필요할 때 함수에 다른 경계를 전달할 수 있습니다.
def binary_search(elements, value, left, right):
if left <= right:
middle = (left + right) // 2
if elements[middle] == value:
return True
elif elements[middle] < value:
return binary_search(elements, value, middle+1, right)
else:
return binary_search(elements, value, left, middle-1)
return False
if __name__ == '__main__':
nums = [1, 2, 3, 4, 5]
print(binary_search(nums, 2, 0, len(nums)-1)) # True
print(binary_search(nums, 10, 0, len(nums)-1)) # False
단점은 이 함수를 호출할 때마다 초기 경계를 전달해야 합니다.
binary_search(nums, 10, 0, len(nums)-1)
제3판
더 나아가 함수를 다른 함수에 중첩하여 기술적 세부 사항을 숨기고 외부 역할 영역에서 변수를 다시 사용하고자 할 수도 있습니다.
def contains(elements, value):
def recursive(left, right):
if left <= right:
midddle = (left + right) // 2
if elements[midddle] == value:
return True
elif elements[midddle] < value:
return recursive(midddle+1, right)
else:
return recursive(left, midddle-1)
return False
return recursive(0, len(elements) - 1)
if __name__ == '__main__':
nums = [1, 2, 3, 4, 5]
print(contains(nums, 2)) # True
print(contains(nums, 10)) # False
폐쇄된 범위 내에서
recursive()
내부 함수를 정의한 경우에도 요소와 값 매개 변수에 접근할 수 있습니다.교체와 귀속 실현 사이의 선택은 일반적으로 성능 고려, 편의성, 그리고 개인의 취향의 최종 결과이다.