1. 程式人生 > 實用技巧 >C++ equal()演算法解析

C++ equal()演算法解析

  equal()演算法比較簡單,它的作用是比較兩個容器是否相等然後返回布林值,它有兩種過載的實現方式,先看下演算法的定義:

 1     // TEMPLATE FUNCTION equal WITH PRED
 2 template<class _InIt1,
 3     class _InIt2,
 4     class _Pr> inline
 5     bool _Equal(_InIt1 _First1, _InIt1 _Last1,
 6         _InIt2 _First2, _Pr _Pred)
 7     {    // compare [_First1, _Last1) to [_First2, ...) using _Pred
8 for (; _First1 != _Last1; ++_First1, (void)++_First2) 9 if (!_Pred(*_First1, *_First2)) 10 return (false); 11 return (true); 12 }

  這是提供第一個容器的頭尾迭代器與第二個容器的頭迭代器,遍歷第一個容器的元素,通過仿函式判斷後,有任一元素不符合條件則返回false,即兩個容器可以不同大小。

  預設的仿函式為equal_to<>,其定義為

 1 template<class
_Ty = void> 2 struct equal_to 3 { // functor for operator== 4 typedef _Ty first_argument_type; 5 typedef _Ty second_argument_type; 6 typedef bool result_type; 7 _CONST_FUN bool operator()(const _Ty& _Left, const _Ty& _Right) const 8 { // apply operator== to operands
9 return (_Left == _Right); 10 } 11 };

  即判斷兩值是否相等,結合equal()演算法可知其實現為判斷兩個容器相同索引的元素是否相等,以第一個容器為比較範圍。

  而equal()的提供兩個容器頭尾迭代器的過載實現則為:

 1 // TEMPLATE FUNCTION equal WITH TWO RANGES, PRED
 2 template<class _InIt1,
 3     class _InIt2,
 4     class _Pr> inline
 5     bool _Equal(_InIt1 _First1, _InIt1 _Last1,
 6         _InIt2 _First2, _InIt2 _Last2, _Pr _Pred,
 7             input_iterator_tag, input_iterator_tag)
 8     {    // compare [_First1, _Last1) to [_First2, _Last2)
 9         // using _Pred, arbitrary iterators
10     _DEBUG_POINTER_IF(_First1 != _Last1 && _First2 != _Last2, _Pred);
11     for (; _First1 != _Last1 && _First2 != _Last2; ++_First1, (void)++_First2)
12         if (!_Pred(*_First1, *_First2))
13             return (false);
14     return (_First1 == _Last1 && _First2 == _Last2);
15     }

  根據註釋可以得知這種過載適用於任意型別的迭代器,從實現方式上看,其要求兩個容器大小相同且元素相同

 1 template<class _InIt1,
 2     class _InIt2,
 3     class _Pr> inline
 4     bool _Equal(_InIt1 _First1, _InIt1 _Last1,
 5         _InIt2 _First2, _InIt2 _Last2, _Pr _Pred,
 6             random_access_iterator_tag, random_access_iterator_tag)
 7     {    // compare [_First1, _Last1) to [_First2, _Last2)
 8         // using _Pred, random-access iterators
 9     if (_Last1 - _First1 != _Last2 - _First2)
10         return (false);
11     _DEBUG_POINTER_IF(_First1 != _Last1, _Pred);
12     return (_Equal(_First1, _Last1, _First2, _Pred));
13     }

  根據註釋可以得知這種過載適用於隨機讀取型別的迭代器,從實現方式上看,其要求兩個容器大小相同,然後再呼叫第一種形式判斷。
  這兩種形式的過載都要求容器嚴格匹配,相對來說沒有那麼靈活

  下面做個演示:

1 vector<int> a{ 1,2,3 }, b{ 1,2,3,4 };    
2 cout << "以a為比較範圍,判斷a,b是否相同:" << equal(a.begin(),a.end(),b.begin()) << endl;
3 cout << "要求容器相同,判斷a,b是否相同:" << equal(a.begin(), a.end(), b.begin(), b.end()) << endl;

  結果: