Java a déjà une fonction de recherche binaire intégrée qui calcule les bornes inférieures/supérieures pour un élément dans un tableau, il n'est pas nécessaire d'implémenter des méthodes personnalisées.
Lorsque nous parlons de bornes supérieures/inférieures ou de plages égales, nous voulons toujours dire les index d'un conteneur (dans ce cas d'ArrayList), et non les éléments contenus. Considérons un tableau (nous supposons que le tableau est trié, sinon nous le trions d'abord) :
List nums = new ArrayList<>(Arrays.asList(2,3,5,5,7,9,10,18,22));
La fonction de "borne inférieure" doit retourner l'index du tableau, où l'élément doit être inséré pour garder le tableau trié. La "borne supérieure" doit retourner l'index du plus petit élément dans le tableau, qui est plus grand que l'élément recherché. Par exemple
lowerBound(nums, 6)
doit retourner 3, car 3 est la position du tableau (en commençant à compter à partir de 0), où 6 doit être inséré pour garder le tableau trié.
La
upperBound(nums, 6)
doit retourner 4, car 4 est la position du plus petit élément dans le tableau, qui est plus grand que 5 ou 6, (le numéro 7 à la position 4).
En C++ dans la bibliothèque standard les deux algorithmes sont déjà implémentés dans la bibliothèque standard. En Java vous pouvez utiliser
Collections.binarySearch(nums, élément)
pour calculer la position en complexité de temps logarithmique.
Si le tableau contient l'élément, Collections.binarySearch retourne le premier index de l'élément (dans le tableau ci-dessus 2). Sinon, cela retourne un nombre négatif qui spécifie la position dans le tableau du prochain élément plus grand, en comptant à rebours à partir du dernier index du tableau. Le nombre trouvé à cette position est le plus petit élément du tableau qui est plus grand que l'élément que vous recherchez.
Par exemple, si vous appelez
int idx = Collections.binarySearch(nums, 6)
la fonction retourne -5. Si vous comptez à rebours à partir du dernier index du tableau (-1, -2, ...) l'index -5 pointe vers le chiffre 7 - le plus petit chiffre dans le tableau qui est plus grand que l'élément 6.
Conclusion : si le tableau trié contient l'élément recherché, la borne inférieure est la position de l'élément, et la borne supérieure est la position du prochain élément plus grand.
Si le tableau ne contient pas l'élément, la borne inférieure est la position
Math.abs(idx) - 2
et la borne supérieure est la position
Math.abs(idx) - 1
où
idx = Collections.binarySearch(nums, élément)
Et veuillez toujours garder à l'esprit les cas limites. Par exemple, si vous cherchez le chiffre 1 dans le tableau spécifié ci-dessus :
idx = Collections.binarySearch(nums, 1)
La fonction retourne -1. Ainsi, la borne supérieure = Math.abs(idx) - 1 = 0 - l'élément 2 à la position 0. Mais il n'y a pas de borne inférieure pour l'élément 1, car 2 est le plus petit chiffre dans le tableau. La même logique s'applique aux éléments plus grands que le plus grand chiffre dans le tableau : si vous cherchez les bornes inférieures/supérieures du chiffre 25, vous obtiendrez
idx = Collections.binarySearch(nums, 25)
ix = -10. Vous pouvez calculer la borne inférieure : lb = Math.abs(-10) - 2 = 8, c'est la dernière index du tableau, mais il n'y a pas de borne supérieure, car 22 est déjà le plus grand élément dans le tableau et il n'y a pas d'élément à la position 9.
L'équivalent_range spécifie tous les index du tableau dans la plage à partir de l'index de la borne inférieure jusqu'à (mais non inclus) la borne supérieure. Par exemple, l'équivalent_range du chiffre 5 dans le tableau ci-dessus sont les index
[2,3]
L'équivalent_range du chiffre 6 est vide, car il n'y a pas de chiffre 6 dans le tableau.