J'essaie d'implémenter la recherche binaire en python et je l'ai écrit comme suit. Cependant, je ne peux pas le faire arrêter chaque fois que needle_element est plus grand que le plus grand élément du tableau.
Pouvez vous aider? Merci.
def binary_search(array, needle_element):
mid = (len(array)) / 2
if not len(array):
raise "Error"
if needle_element == array[mid]:
return mid
Elif needle_element > array[mid]:
return mid + binary_search(array[mid:],needle_element)
Elif needle_element < array[mid]:
return binary_search(array[:mid],needle_element)
else:
raise "Error"
Dans le cas où needle_element > array[mid]
, vous transmettez actuellement array[mid:]
à l'appel récursif. Mais vous savez que array[mid]
est trop petit, vous pouvez donc passer array[mid+1:]
à la place (et ajuster l'index renvoyé en conséquence).
Si l'aiguille est plus grande que tous les éléments du tableau, cette procédure vous donnera éventuellement un tableau vide et une erreur sera générée comme prévu.
Remarque: la création d'un sous-tableau à chaque fois entraînera de mauvaises performances pour les grands tableaux. Il vaut mieux passer dans les limites du tableau à la place.
Il serait bien préférable de travailler avec les index lower
et upper
comme Lasse V. Karlsen suggéraient dans un commentaire à la question.
Ce serait le code:
def binary_search(array, target):
lower = 0
upper = len(array)
while lower < upper: # use < instead of <=
x = lower + (upper - lower) // 2
val = array[x]
if target == val:
return x
Elif target > val:
if lower == x: # these two are the actual lines
break # you're looking for
lower = x
Elif target < val:
upper = x
lower < upper
s'arrêtera une fois que vous aurez atteint le plus petit nombre (en partant de la gauche)if lower == x: break
s'arrêtera une fois que vous avez atteint le nombre le plus élevé (à droite)Exemple:
>>> binary_search([1,5,8,10], 5) # return 1
1
>>> binary_search([1,5,8,10], 0) # return None
>>> binary_search([1,5,8,10], 15) # return None
array [mid:] crée une nouvelle sous-copie à chaque fois que vous l'appelez = slow. Vous utilisez également la récursivité, qui, en Python, est lente.
Essaye ça:
def binarysearch(sequence, value):
lo, hi = 0, len(sequence) - 1
while lo <= hi:
mid = (lo + hi) // 2
if sequence[mid] < value:
lo = mid + 1
Elif value < sequence[mid]:
hi = mid - 1
else:
return mid
return None
Pourquoi ne pas utiliser le module bissect? Il devrait faire le travail dont vous avez besoin - moins de code à maintenir et à tester.
Vous pouvez améliorer votre algorithme comme le suggèrent les autres, mais voyons d'abord pourquoi cela ne fonctionne pas:
Vous êtes bloqué dans une boucle parce que si needle_element > array[mid]
, vous incluez l'élément mid
dans le tableau divisé en deux que vous recherchez ensuite. Donc si aiguille n’est pas dans le tableau, vous allez éventuellement chercher un tableau de longueur un pour toujours. Passez plutôt array[mid+1:]
(c'est légal même si mid+1
n'est pas un index valide) et vous appellerez éventuellement votre fonction avec un tableau de longueur zéro. Donc, len(array) == 0
signifie "non trouvé", pas une erreur. Manipulez-le de manière appropriée.
def binary_search(array, target):
low = 0
mid = len(array) / 2
upper = len(array)
if len(array) == 1:
if array[0] == target:
print target
return array[0]
else:
return False
if target == array[mid]:
print array[mid]
return mid
else:
if mid > low:
arrayl = array[0:mid]
binary_search(arrayl, target)
if upper > mid:
arrayu = array[mid:len(array)]
binary_search(arrayu, target)
if __== "__main__":
a = [3,2,9,8,4,1,9,6,5,9,7]
binary_search(a,9)
Toutes les réponses ci-dessus sont vraies, mais je pense que cela aiderait à partager mon code
def binary_search(number):
numbers_list = range(20, 100)
i = 0
j = len(numbers_list)
while i < j:
middle = int((i + j) / 2)
if number > numbers_list[middle]:
i = middle + 1
else:
j = middle
return 'the index is '+str(i)
Utilisation de la récursivité:
def binarySearch(arr,item):
c = len(arr)//2
if item > arr[c]:
ans = binarySearch(arr[c+1:],item)
if ans:
return binarySearch(arr[c+1],item)+c+1
Elif item < arr[c]:
return binarySearch(arr[:c],item)
else:
return c
binarySearch([1,5,8,10,20,50,60],10)
Sans les index inférieur/supérieur, cela devrait également faire:
def exists_element(element, array):
if not array:
yield False
mid = len(array) // 2
if element == array[mid]:
yield True
Elif element < array[mid]:
yield from exists_element(element, array[:mid])
else:
yield from exists_element(element, array[mid + 1:])
C'est une solution récursive, je pense que c'est plus propre que de copier des tableaux partiels et de garder une trace des index pour le retour
def binarySearch(elem, arr):
# return the index at which elem lies, or return false
# if elem is not found
# pre: array must be sorted
return binarySearchHelper(elem, arr, 0, len(arr) - 1)
def binarySearchHelper(elem, arr, start, end):
if start > end:
return False
mid = (start + end)//2
if arr[mid] == elem:
return mid
Elif arr[mid] > elem:
# recurse to the left of mid
return binarySearchHelper(elem, arr, start, mid - 1)
else:
# recurse to the right of mid
return binarySearchHelper(elem, arr, mid + 1, end)
Il retourne l'index de la clé dans le tableau en utilisant récursif.
round () est une fonction qui convertit float en entier, rend le code rapide et va au cas attendu [O (logn)].
A=[1,2,3,4,5,6,7,8,9,10]
low = 0
hi = len(A)
v=3
def BS(A,low,hi,v):
mid = round((hi+low)/2.0)
if v == mid:
print ("You have found dude!" + " " + "Index of v is ", A.index(v))
Elif v < mid:
print ("Item is smaller than mid")
hi = mid-1
BS(A,low,hi,v)
else :
print ("Item is greater than mid")
low = mid + 1
BS(A,low,hi,v)
BS(A,low,hi,v)
Si vous effectuez une recherche binaire, je suppose que le tableau est trié. Si cela est vrai, vous devriez pouvoir comparer le dernier élément du tableau au needle_element
. Comme le dit la pieuvre, cela peut être fait avant le début de la recherche.
Vous pouvez simplement vérifier que needle_element
est dans les limites du tableau avant de commencer. Cela le rendra plus efficace aussi, puisque vous n’aurez pas à faire plusieurs étapes pour arriver à la fin.
if needle_element < array[0] or needle_element > array[-1]:
# do something, raise error perhaps?