源码分析for_each,unique,stable_sort,find_if

源码分析for_each,unique,stable_sort,find_if

unique

link

link2

这个函数只能对"相同元素在并邻在一块的"序列进行去重. 不能对相同元素七零八落地分布的一般序列进行去重, 可以对一般数组进行排序后再用unique()实现去重目的即可, 因为排好序的的序列里面相同元素一定存储在连续的地址块. 提醒, 该函数实现去重功能并不是把相同元素删除

返回的是不重复元素的最后一个不包括自己,在容器里都是维持着左闭右开的区间

unique的源码解析

 unique(_ForwardIterator __first, _ForwardIterator __last)
    {
      // concept requirements
      __glibcxx_function_requires(_Mutable_ForwardIteratorConcept<
				  _ForwardIterator>)
      __glibcxx_function_requires(_EqualityComparableConcept<
		     typename iterator_traits<_ForwardIterator>::value_type>)
      __glibcxx_requires_valid_range(__first, __last);

      return std::__unique(__first, __last,
			   __gnu_cxx::__ops::__iter_equal_to_iter());
    }
_unique(_ForwardIterator __first, _ForwardIterator __last,
	     _BinaryPredicate __binary_pred)
    {
      // Skip the beginning, if already unique.
      __first = std::__adjacent_find(__first, __last, __binary_pred);
      if (__first == __last)
	return __last;

      // Do the real copy work.
      _ForwardIterator __dest = __first;
      ++__first;
      while (++__first != __last)
	if (!__binary_pred(__dest, __first))
	  *++__dest = _GLIBCXX_MOVE(*__first);
      return ++__dest;
    }

其实关键就在于

  while (++__first != __last)
	if (!__binary_pred(__dest, __first))
	  *++__dest = _GLIBCXX_MOVE(*__first);
      return ++__dest;

去掉重命名和宏替换以后

  while (++__first != __last)
	if (__dest != __first))
	  *++__dest = std::move(*__first);
      return ++__dest;

其实就是每一次去找后面不同的进行替换

比如 1 2 2 2 4 4 5 下标在 0 1这时候 0 1 对应数值不相等所以 *++dest =*first就相当于没有交换

1 2 2 2 4 4 5 下标分别在 1 2相等继续++first,直到first到达下标4交换

1 2 4 2 4 4 5 下标为 2 5 又相等 ++first

1 2 4 2 4 4 5 下标 2 6 不等 *dest = *first

1 2 4 5 4 4 5 下标 3 6 这时候++first到达终点返回 ++dest也就返回下标在4的迭代器

for_each()

  template<typename _InputIterator, typename _Function>
    _Function
    for_each(_InputIterator __first, _InputIterator __last, _Function __f)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_requires_valid_range(__first, __last);
      for (; __first != __last; ++__first)
	__f(*__first);
      return _GLIBCXX_MOVE(__f);
    }

其实就是执行可调用表达式进行调用,参数就是每一个迭代器里面的内容

find_if

  template<typename _InputIterator, typename _Predicate>
    inline _InputIterator
    find_if(_InputIterator __first, _InputIterator __last,
	    _Predicate __pred)
    {
      // concept requirements
      __glibcxx_function_requires(_InputIteratorConcept<_InputIterator>)
      __glibcxx_function_requires(_UnaryPredicateConcept<_Predicate,
	      typename iterator_traits<_InputIterator>::value_type>)
      __glibcxx_requires_valid_range(__first, __last);

      return std::__find_if(__first, __last,
			    __gnu_cxx::__ops::__pred_iter(__pred));
    }
  template<typename _InputIterator, typename _Predicate>
    inline _InputIterator
    __find_if(_InputIterator __first, _InputIterator __last,
	      _Predicate __pred, input_iterator_tag)
    {
      while (__first != __last && !__pred(__first))
	++__first;
      return __first;
    }

其实就是找到满足可调用表达式里面第一个条件的迭代器

可调用表达式包括,函数,函数指针,std::bind,lambda表达式,重载()调用运算符的类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值