STL复习之算法四

   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;
}

       执行结果:

猜你喜欢

转载自blog.csdn.net/weixin_40825228/article/details/81079897