"유용한"C ++ 바이너리 검색 알고리즘은 어디서 구할 수 있습니까?
std::binary_search
표준 라이브러리의 <algorithm>
헤더 와 같은 C ++ STL 컨테이너와 호환되는 이진 검색 알고리즘이 필요하지만 요소가 존재하는지 알려주는 단순한 부울이 아닌 결과를 가리키는 반복자를 반환해야합니다.
(참고로, 표준위원회가 binary_search 용 API를 정의 할 때 도대체 무슨 생각을했을까요?!)
여기서 내 주요 관심사는 바이너리 검색의 속도가 필요하다는 것입니다. 따라서 아래에 언급 된 것처럼 다른 알고리즘으로 데이터를 찾을 수 있지만 바이너리의 이점을 얻기 위해 데이터가 정렬되어 있다는 사실을 활용하고 싶습니다. 선형 검색이 아닌 검색입니다.
지금까지 lower_bound
와 upper_bound
데이텀이없는 경우 실패합니다 :
//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
참고 : 컨테이너와 호환되는 한 std 네임 스페이스에 속하지 않는 알고리즘을 사용해도 괜찮습니다. 예를 들어, boost::binary_search
.
이 그러한 기능은 없지만, 당신은 사용하여 간단한 하나를 쓸 수 있습니다 std::lower_bound
, std::upper_bound
또는 std::equal_range
.
간단한 구현은 다음과 같습니다.
template<class Iter, class T>
Iter binary_find(Iter begin, Iter end, T val)
{
// Finds the lower bound in at most log(last - first) + 1 comparisons
Iter i = std::lower_bound(begin, end, val);
if (i != end && !(val < *i))
return i; // found
else
return end; // not found
}
또 다른 해결책은 std::set
요소의 순서를 보장 iterator find(T key)
하고 주어진 항목에 반복기를 반환하는 메서드 를 제공 하는를 사용하는 것입니다. 그러나 요구 사항이 집합 사용과 호환되지 않을 수 있습니다 (예 : 동일한 요소를 여러 번 저장해야하는 경우).
를 봐야 std::equal_range
합니다. 모든 결과의 범위에 대해 한 쌍의 반복자를 반환합니다.
그 세트가 있습니다.
http://www.sgi.com/tech/stl/table_of_contents.html
검색 :
별도의 참고 :
그들은 아마도 컨테이너를 검색하면 하나 이상의 결과를 검색 할 수 있다고 생각했을 것입니다. 그러나 존재 여부를 테스트해야하는 이상한 경우에는 최적화 된 버전도 좋을 것입니다.
std :: lower_bound가 원하는 수준에 비해 너무 낮은 경우 boost :: container :: flat_multiset 을 확인하는 것이 좋습니다 . 이진 검색을 사용하여 정렬 된 벡터로 구현 된 std :: multiset의 드롭 인 대체입니다.
std :: lower_bound () :)
이 기능을 확인하십시오. qBinaryFind :
RandomAccessIterator qBinaryFind ( RandomAccessIterator begin, RandomAccessIterator end, const T & value )
범위 (시작, 끝)의 이진 검색을 수행하고 값이 발생한 위치를 반환합니다. 값이 없으면 end를 반환합니다.
[시작, 끝) 범위의 항목은 오름차순으로 정렬해야합니다. qSort ()를 참조하십시오.
동일한 값이 많이 발생하면 그중 하나가 반환 될 수 있습니다. 더 세밀한 제어가 필요한 경우 qLowerBound () 또는 qUpperBound ()를 사용하십시오.
예:
QVector<int> vect; vect << 3 << 3 << 6 << 6 << 6 << 8; QVector<int>::iterator i = qBinaryFind(vect.begin(), vect.end(), 6); // i == vect.begin() + 2 (or 3 or 4)
이 함수는 Qt 라이브러리 <QtAlgorithms>
의 일부인 헤더에 포함되어 있습니다.
표준 라이브러리에 포함되지 않은 이유를 궁금해하는 가장 짧은 구현 :
template<class ForwardIt, class T, class Compare=std::less<>>
ForwardIt binary_find(ForwardIt first, ForwardIt last, const T& value, Compare comp={})
{
// Note: BOTH type T and the type after ForwardIt is dereferenced
// must be implicitly convertible to BOTH Type1 and Type2, used in Compare.
// This is stricter than lower_bound requirement (see above)
first = std::lower_bound(first, last, value, comp);
return first != last && !comp(value, *first) ? first : last;
}
에서 https://en.cppreference.com/w/cpp/algorithm/lower_bound
범위 내의 위치를 반환하는 솔루션은 반복기에 대한 연산 만 사용하여 다음과 같을 수 있습니다 (반복자가 산술을 수행하지 않는 경우에도 작동해야 함).
template <class InputIterator, typename T>
size_t BinarySearchPos(InputIterator first, InputIterator last, const T& val)
{
const InputIterator beginIt = first;
InputIterator element = first;
size_t p = 0;
size_t shift = 0;
while((first <= last))
{
p = std::distance(beginIt, first);
size_t u = std::distance(beginIt, last);
size_t m = (p+u)/2;
std::advance(element, m - shift);
shift = m;
if(*element == val)
return m; // value found at position m
if(val > *element)
first = element++;
else
last = element--;
}
// if you are here the value is not present in the list,
// however if there are the value should be at position u
// (here p==u)
return p;
}
int BinarySearch(vector<int> array,int var)
{
//array should be sorted in ascending order in this case
int start=0;
int end=array.size()-1;
while(start<=end){
int mid=(start+end)/2;
if(array[mid]==var){
return mid;
}
else if(var<array[mid]){
end=mid-1;
}
else{
start=mid+1;
}
}
return 0;
}
Example: Consider an array, A=[1,2,3,4,5,6,7,8,9] Suppose you want to search the index of 3 Initially, start=0 and end=9-1=8 Now, since start<=end; mid=4; (array[mid] which is 5) !=3 Now, 3 lies to the left of mid as its smaller than 5. Therefore, we only search the left part of the array Hence, now start=0 and end=3; mid=2.Since array[mid]==3, hence we got the number we were searching for. Hence, we return its index which is equal to mid.
참고URL : https://stackoverflow.com/questions/446296/where-can-i-get-a-useful-c-binary-search-algorithm
'Programing' 카테고리의 다른 글
Postgres : "오류 : 캐시 된 계획은 결과 유형을 변경하면 안됩니다." (0) | 2020.08.22 |
---|---|
장식 된 기능의 서명 보존 (0) | 2020.08.21 |
gcc std :: unordered_map 구현이 느립니까? (0) | 2020.08.21 |
Python에서 클래스 속성을 문서화하는 방법은 무엇입니까? (0) | 2020.08.21 |
작성하는 모든 프로그램에서 사용할 Android 개발 용 라이브러리를 만드는 방법은 무엇입니까? (0) | 2020.08.21 |