mismatch
頭文件'mismatch.hpp'包含了stl算法mismatch的兩個變體。該算法在兩個序列中查找第一個破壞兩序列一致性的元素位置。
在(被提倡使用的)C++14 前,該算法std::mismatch帶了三個迭代器一個用來做比較的可選謂詞。前連個迭代器[first1,last1)定義了一個序列範圍,第二個迭代器first2定義了第二個序列的起始位置。算法假設第二個迭代器的長度與第一個迭代器的一樣長。
在C++14,該算法的兩個變體函數被推薦使用,他們帶四個迭代器以及一個可選的用作比較的謂詞 。這四個迭代器[first1, last1)、[first2, last2)精確的定義了兩個序列(之前的算法定義第二個序列是隱式的)。這將使得在更多的情況下能獲得正確的結果。
考慮如下兩個序列
auto seq1 = { 0, 1, 2 };
auto seq2 = { 0, 1, 2, 3, 4 };
std::mismatch ( seq1.begin (), seq1.end (), seq2.begin ()); // <3, 3>
std::mismatch ( seq2.begin (), seq2.end (), seq1.begin ()); // Undefined behavior
std::mismatch ( seq1.begin (), seq1.end (), seq2.begin (), seq2.end ()); // <3, 3>
seq2的前面N個元素與seq1的一樣。在第二個例子中,算法將會讀取超過seq1結尾後的內容,這將導致未定義的行爲。然而,假如兩個序列的是完全指定的,很容易看出,不匹配的位置將是哪裏。(即,連個序列的範圍完全在傳遞參數的時候指定好,也就是使用4個迭代器)
官方API
mismatch函數返回一對迭代器(pair),這對迭代器標註在兩個序列中第一次元素不匹配的位置(即,每個序列各取一個位置,因此放回pair)。假如兩個序列完全匹配,程序返回元素結束後的迭代器位置(end()位置)。其中一個版本使用std::equal_to做比較,另一個版本使用傳遞過來的謂詞做比較。
template <class InputIterator1, class InputIterator2>
std::pair<InputIterator1, InputIterator2>
mismatch ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2 );
template <class InputIterator1, class InputIterator2, class BinaryPredicate>
std::pair<InputIterator1, InputIterator2>
mismatch ( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, InputIterator2 last2, BinaryPredicate pred );
例子假設有容器 c1 { 0, 1, 2, 3, 14, 15 },C2{ 1, 2, 3 }
//返回<c1.begin(), c2.begin()> 他們的第一個元素就不匹配
mismatch ( c1.begin(), c1.end(), c2.begin(), c2.end())
//<c1.begin() + 4, c2.end ()>
//這裏所有c2總的元素,滿足傳遞過去的c1中的自序列範圍,因此返回的都是越過結尾的位置
mismatch ( c1.begin() + 1, c1.begin() + 4, c2.begin(), c2.end())
//注意,c1.begin()+4這個迭代器標註的是第一個序列的越過結尾位置,並沒有用來做比較,兩個元素比較的是一個左閉右開的區間範圍
//返回<c1.end(), c2.end()>
mismatch ( c1.end(),c1.end(),c2.end(), c2.end())
迭代器要求
mismatch 將作用於除了output迭代器外的所有迭代器。
時間複雜度
兩個變體函數的時間複雜度都是O(N);也就是說,他們僅僅比較序列中的元素一次。假如在序列中發現有任何一個元素不相同,則函數馬上返回,不管餘下的元素。
異常安全
兩個函數都是傳值調用,並且不依靠任何全局狀態。因此這些函數提供了很強的異常安全性保證。
注意
假如連個序列相同(或者都爲空),則mismatch函數返回兩個序列的超出末端迭代器。
這四個迭代器版本的mismatch函數是c++14標準的一部分,當c++14標準庫的實現變得可用,那麼應該使用這個標準庫的實現。