1、unique。算法unique能够移除重复的元素。每当在区间[first,last)内有重复元素群,它便移除该元素群中的第一个以后的连续的重复元素。注意,unique只能移除连续的相邻的连续元素,如果想要移除所有(包括不相邻的元素)重复元素,需要先对序列排序,使所有重复的元素都相邻。
测试代码:
void traverseEle(const std::vector<int> array)
{
int index=1;
for(auto it=array.begin();it!=array.end();++it)
std::cout<</*index++<<"\t"<<*/*it<<"\t";
std::cout<<std::endl;
}
//测试函数
int main()
{
std::vector<int> intArray={1,2,3,4,5,6,6,7,8};
std::cout<<"before unique:\n";
traverseEle(intArray);
auto it=std::unique(intArray.begin(),intArray.end());
intArray.erase(it,intArray.end());
std::cout<<"after unique:\n";
traverseEle(intArray);
return 0;
}
执行结果:
2、unique_copy()。算法unique_copy可从[first,last)中将元素复制到以result开头的区间上;如果面对相邻重复元素群,只会复制其中第一个元素。返回的迭代器指向以result开头的区间的最后一个元素的下一个位置。
实现:
template<typename _ForwardIterator, typename _OutputIterator,
typename _BinaryPredicate>
_OutputIterator
__unique_copy(_ForwardIterator __first, _ForwardIterator __last,
_OutputIterator __result, _BinaryPredicate __binary_pred,
forward_iterator_tag, output_iterator_tag)
{
// concept requirements -- iterators already checked
__glibcxx_function_requires(_BinaryPredicateConcept<_BinaryPredicate,
typename iterator_traits<_ForwardIterator>::value_type,
typename iterator_traits<_ForwardIterator>::value_type>)
_ForwardIterator __next = __first;
*__result = *__first;
while (++__next != __last)
if (!__binary_pred(__first, __next))
{
__first = __next;
*++__result = *__first;
}
return ++__result;
}
测试代码:
void traverseEle(const std::vector<int> array)
{
int index=1;
for(auto it=array.begin();it!=array.end();++it)
std::cout<</*index++<<"\t"<<*/*it<<"\t";
std::cout<<std::endl;
}
//测试函数
int main()
{
std::vector<int> intArray={1,2,3,4,5,6,6,7,8};
std::vector<int> intArrayCopy;
intArrayCopy.resize(intArray.size());
std::cout<<"before unique:\n";
traverseEle(intArrayCopy);
std::unique_copy(intArray.begin(),intArray.end(),intArrayCopy.begin());
std::cout<<"after unique:\n";
traverseEle(intArrayCopy);
return 0;
}
执行结果:
3、lower_bound(应用于有序区间,是二分查找的一个版本)。
试图在元素已经排好序的区间[first,last)中寻找第一个不小于给定值value的元素 ,若整个区间都不存在这样的元素,则返回这个区间的最后一个元素的下一个位置,即last。
函数原型:
template<typename _ForwardIterator, typename _Tp, typename _Compare>
_ForwardIterator
__lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
[__first,__last)构成有序区间,__val是要在这个给定区间进行查找的值,__comp是指定的二元运算符。
算法实现:
template<typename _ForwardIterator, typename _Tp, typename _Compare>
_ForwardIterator
__lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
{
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
_DistanceType __len = std::distance(__first, __last);//计算区间长度
while (__len > 0)
{
_DistanceType __half = __len >> 1; //区间长度除以2
_ForwardIterator __middle = __first;//__middle初始化为指向当前区间的起点元素
std::advance(__middle, __half); //此时__middle指向当前区间的中间点元素
if (__comp(__middle, __val)) //__comp(__middle,__val)==true
{ //在当前区间的后半段继续查找
__first = __middle; //注意到要除去当前区间的__middle所指向的元素
++__first;
__len = __len - __half - 1;
}
else //__comp(__middle,__val)==false,在前半区间继续查找
__len = __half;
} //end of while
return __first;
}
测试代码:
//测试函数
int main()
{
std::vector<int> intArray={1,2,3,4,5,6,6,7,8};
auto it=std::lower_bound(intArray.begin(),intArray.end(),6);
for(;it!=intArray.end();++it)
std::cout<<*it<<"\t";
std::cout<<std::endl;
return 0;
}
执行结果:
4、upper_bound()。这个算法试图在已经有序的区间[first,last)内查找给定查找的值value,更确切地说,它会返回在“不破坏元素顺序的前提下,可插入value的最后一个合适的位置”(《STL源码剖析》第377页)。若value在区间内存在,则返回value在区间内最后出现的位置的下一个位置。
算法实现:
template<typename _ForwardIterator, typename _Tp, typename _Compare>
_ForwardIterator
__lower_bound(_ForwardIterator __first, _ForwardIterator __last,
const _Tp& __val, _Compare __comp)
{
typedef typename iterator_traits<_ForwardIterator>::difference_type
_DistanceType;
_DistanceType __len = std::distance(__first, __last);//计算区间长度
while (__len > 0)
{
_DistanceType __half = __len >> 1; //区间长度除以2
_ForwardIterator __middle = __first;//__middle初始化为指向当前区间的起点元素
std::advance(__middle, __half); //此时__middle指向当前区间的中间点元素
if (__comp(__middle, __val)) //__comp(__middle,__val)==true
__len = __half; //在当前区间的前半段继续查找
else
{
__first = __middle; //在当前区间后半段继续查找
++__first; //注意到要除去当前区间的__middle所指向的元素
__len = __len - __half - 1;
}
} //end of while
return __first;
}
测试代码:
//测试函数
int main()
{
std::vector<int> intArray={1,2,3,4,5,6,6,7,8};
auto it=std::upper_bound(intArray.begin(),intArray.end(),6);
for(;it!=intArray.end();++it)
std::cout<<*it<<"\t";
std::cout<<std::endl;
return 0;
}
执行结果:
5、binary_search(first,last,value)。试图在已经排好序的序列中查找值为value的元素,若查找到了,返回为true;否则,返回为false。
算法实现:
template<class ForwardIterator,class T>
bool binary_search(ForwardIterator first,ForwardIterator last,const T& value>
{
ForwardItetator i=lower_bound(first,last,value);
return i!=last&&!(value<*i);
}
测试代码:
int main()
{
std::vector<int> intArray={1,2,3,4,5,6,6,7,8};
auto it1=std::binary_search(intArray.begin(),intArray.end(),6);
auto it2=std::binary_search(intArray.begin(),intArray.end(),16);
if(it1=true)
std::cout<<"has find!\n";
else
std::cout<<"has not find!\n";
if(it2==true)
std::cout<<"has find!\n";
else
std::cout<<"has not find!\n";
return 0;
}
执行结果: