Preciso de um algoritmo de pesquisa binária que seja compatível com os contêineres C ++ STL, algo como std::binary_search
no <algorithm>
cabeçalho da biblioteca padrão , mas preciso retornar o iterador que aponta para o resultado, não um booleano simples informando se o elemento existe.
(Por outro lado, o que diabos o comitê padrão estava pensando quando definiu a API para binary_search ?!)
Minha principal preocupação aqui é que preciso da velocidade de uma pesquisa binária, embora possa encontrar os dados com outros algoritmos, como mencionado abaixo, quero aproveitar o fato de que meus dados são classificados para obter os benefícios de um binário pesquisa, não uma pesquisa linear.
até agora lower_bound
e upper_bound
falhar se o dado estiver faltando:
//lousy pseudo code
vector(1,2,3,4,6,7,8,9,0) //notice no 5
iter = lower_bound_or_upper_bound(start,end,5)
iter != 5 && iter !=end //not returning end as usual, instead it'll return 4 or 6
Observação: também estou bem usando um algoritmo que não pertence ao namespace std, desde que seja compatível com contêineres. Tipo, digamos boost::binary_search
,.
fonte
Respostas:
Não existem tais funções, mas você pode escrever uma simples usando
std::lower_bound
,std::upper_bound
oustd::equal_range
.Uma implementação simples pode ser
Outra solução seria usar a
std::set
, que garante a ordem dos elementos e fornece um métodoiterator find(T key)
que retorna um iterador para o item fornecido. No entanto, seus requisitos podem não ser compatíveis com o uso de um conjunto (por exemplo, se você precisar armazenar o mesmo elemento várias vezes).fonte
*i == val
! Em vez disso, use!(val < *i)
. A razão é quelower_bound
usa<
, não==
(ouT
seja, não é nem mesmo exigido que seja comparável em igualdade). (Veja o STL efetivo de Scott Meyers para uma explicação da diferença entre igualdade e equivalência .)end
. Os intervalos na biblioteca padrão C ++ são representados com intervalos semiabertos: o iterador final "aponta" após o último elemento. Como tal, pode ser retornado por algoritmos para indicar que nenhum valor foi encontrado.Você deveria dar uma olhada
std::equal_range
. Ele retornará um par de iteradores para o intervalo de todos os resultados.fonte
Existe um conjunto deles:
http://www.sgi.com/tech/stl/table_of_contents.html
Procurar por:
Em uma nota separada:
Eles provavelmente estavam pensando que pesquisar contêineres poderia levar a mais de um resultado. Mas na ocasião ímpar em que você só precisa testar a existência, uma versão otimizada também seria bom.
fonte
Se std :: lower_bound for de nível muito baixo para o seu gosto, você pode querer verificar boost :: container :: flat_multiset . É uma substituição drop-in para std :: multiset implementado como um vetor ordenado usando busca binária.
fonte
A implementação mais curta, perguntando por que não está incluída na biblioteca padrão:
De https://en.cppreference.com/w/cpp/algorithm/lower_bound
fonte
Verifique esta função, qBinaryFind :
A função está incluída no
<QtAlgorithms>
cabeçalho que faz parte da biblioteca Qt .fonte
std :: lower_bound () :)
fonte
Exemplo: Considere uma matriz, A = [1,2,3,4,5,6,7,8,9] Suponha que você queira pesquisar o índice de 3 Inicialmente, início = 0 e fim = 9-1 = 8 Agora , desde início <= fim; mid = 4; (array [mid] que é 5)! = 3 Agora, 3 está à esquerda do meio, pois é menor que 5. Portanto, pesquisamos apenas a parte esquerda do array. Portanto, agora start = 0 e end = 3; mid = 2. Desde array [mid] == 3, portanto, obtivemos o número que estávamos procurando. Portanto, retornamos seu índice que é igual a mid.
fonte
Uma solução que retorna a posição dentro do intervalo pode ser assim, usando apenas operações em iteradores (deve funcionar mesmo se o iterador não fizer cálculos):
fonte