Boost 學習之演算法篇 equal
標頭檔案'equal.hpp' 包含一個STL演算法 equal 的兩個變種。該演算法測試兩個序列是否包含相同的值。在(被提倡使用的)C++14 以前的版本中,stl::equal 函式帶有三個迭代器以及一個可選的用作比較的謂詞。前兩個迭代器[first1,last1)定義了一個引數序列,第三個迭代器first2定義了第二個引數序列的開始位置。演算法假設第二個序列長度與第一個一樣長。
在C++14中,兩個新的equal演算法的變體被推薦使用。他們帶有4個迭代器以及一個可選的用作比較的謂詞引數。4個迭代器[first1, last1) 和 [first2, last2)明確的定義了兩個序列範圍。這樣做使得他們在更多地情況下也適用,避免了其他未定義的行為。
考慮一下如下兩個序列:
auto seq1 = { 0, 1, 2 };
auto seq2 = { 0, 1, 2, 3, 4 };
// 返回true //備註,演算法假設第二個序列長度與第一個一樣長。按照如下傳遞引數的情況看,seq2 在與seq1長度相同的範圍內有相同的元素 std::equal ( seq1.begin (), seq1.end (), seq2.begin ()); //為什麼未定義?因為seq1在長度與seq2長度一樣長的時候,seq1部分元素是未定義的 std::equal ( seq2.begin (), seq2.end (), seq1.begin ()); // 這是未定義的行為 std::equal ( seq1.begin (), seq1.end (), seq2.begin (), seq2.end ()); // 返回false
你可能確切的說第一個例子返回true是正確的,儘管序列並不一致。在序列seq2的前N個元素確實與序列seq1中的元素一致——雖然那並不是seq2的全部元素。但是在第二個例子中,演算法將會讀取越過seq1結尾的元素,導致未定義的行為(程式崩潰、不正確的行為、像懷孕的貓一樣不可預測)。
然而,假如兩個序列完全一致,毫無疑問,他們是相等的。
官方API
equal函式返回true,假如兩個序列比較後相等;比如,假如每一個在序列中的元素與另一個序列中對應的元素相同的話。其中一個版本使用std::equal_to來做比較;另一個版本通過傳遞謂詞做比較。
template <class InputIterator1, class InputIterator2> bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2 ); template <class InputIterator1, class InputIterator2, class BinaryPredicate> bool equal ( InputIterator1 first1, InputIterator1 last1, InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred );
例子
假設有一個容器c1 {0,1,2,3,14,15},以及容器c2 {1,2,3},如下操作:
equal ( c1.begin (), c1.end (), c2.begin (), c2.end ()) --> false
equal ( c1.begin () + 1, c1.begin () + 3, c2.begin (), c2.end ()) --> true
//空序列總是相等的
equal ( c1.end (), c1.end (), c2.end (), c2.end ()) --> true
迭代器要求
equal演算法可作用於出來輸出迭代器之外的所有迭代器。
時間複雜度
equal的兩個變體的時間複雜度都是O(N);也就是說,他們比較序列中的所有元素僅僅一次。如果發現序列中的任何一個位置的元素與另一個序列不相等,演算法將馬上停止比較。
異常安全
equal的兩種變體都傳值或者傳引用呼叫他們的引數,兩種變體不依賴任何全域性的狀態。因此他們提供了很強的的異常安全保證。
注意
equal的四個迭代器版本屬於C++14 標準。 當C ++14標準庫的實現變得可用,應使用標準庫的實現。當equal作用於兩個空序列時候,不論傳遞的謂詞是什麼都返回true。