名稱空間
變體
操作

std::equal

來自 cppreference.com
< cpp‎ | 演算法
 
 
演算法庫
有約束演算法與針對範圍的演算法 (C++20)
有約束的演算法,例如 ranges::copyranges::sort 等……
執行策略 (C++17)
排序及相關操作
劃分操作
排序操作
二分搜尋操作
(於已劃分範圍上)
集合操作(於已排序範圍上)
歸併操作(於已排序範圍上)
堆操作
最小/最大值操作
(C++11)
(C++17)
字典序比較操作
排列操作
C 庫
數值操作
未初始化記憶體上的操作
 
定義於標頭檔案 <algorithm>
template< class InputIt1, class InputIt2 >

bool equal( InputIt1 first1, InputIt1 last1,

            InputIt2 first2 );
(1) (C++20 起為 constexpr)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >

bool equal( ExecutionPolicy&& policy,
            ForwardIt1 first1, ForwardIt1 last1,

            ForwardIt2 first2 );
(2) (C++17 起)
template< class InputIt1, class InputIt2, class BinaryPred >

bool equal( InputIt1 first1, InputIt1 last1,

            InputIt2 first2, BinaryPred p );
(3) (C++20 起為 constexpr)
template< class ExecutionPolicy,

          class ForwardIt1, class ForwardIt2, class BinaryPred >
bool equal( ExecutionPolicy&& policy,
            ForwardIt1 first1, ForwardIt1 last1,

            ForwardIt2 first2, BinaryPred p );
(4) (C++17 起)
template< class InputIt1, class InputIt2 >

bool equal( InputIt1 first1, InputIt1 last1,

            InputIt2 first2, InputIt2 last2 );
(5) (C++14 起)
(C++20 起為 constexpr)
template< class ExecutionPolicy, class ForwardIt1, class ForwardIt2 >

bool equal( ExecutionPolicy&& policy,
            ForwardIt1 first1, ForwardIt1 last1,

            ForwardIt2 first2, ForwardIt2 last2 );
(6) (C++17 起)
template< class InputIt1, class InputIt2, class BinaryPred >

bool equal( InputIt1 first1, InputIt1 last1,

            InputIt2 first2, InputIt2 last2, BinaryPred p );
(7) (C++14 起)
(C++20 起為 constexpr)
template< class ExecutionPolicy,

          class ForwardIt1, class ForwardIt2, class BinaryPred >
bool equal( ExecutionPolicy&& policy,
            ForwardIt1 first1, ForwardIt1 last1,

            ForwardIt2 first2, ForwardIt2 last2, BinaryPred p );
(8) (C++17 起)

檢查 [first1, last1) 範圍和從 first2 開始的範圍是否相等。

  • 對於過載 (1-4),第二個範圍有 std::distance(first1, last1) 個元素。
  • 對於過載 (5-8),第二個範圍是 [first2, last2)。
1,5) 使用 operator== 比較元素。
3,7) 使用給定的二元謂詞 p 比較元素。
2,4,6,8) 與 (1,3,5,7) 相同,但根據 policy 執行。
僅當滿足所有以下條件時,這些過載才參與過載決議

std::is_execution_policy_v> 為 true。

(C++20 前)

std::is_execution_policy_v> 為 true。

(C++20 起)

目錄

[edit] 引數

first1, last1 - 定義要比較的第一個元素範圍的迭代器對
first2, last2 - 定義要比較的第二個元素範圍的迭代器對
policy - 要使用的 執行策略
p - 二元謂詞,如果元素應被視為相等,則返回 true。

謂詞函式的簽名應等效於以下內容:

 bool pred(const Type1 &a, const Type2 &b);

雖然簽名不需要包含 const &,但函式不得修改傳遞給它的物件,並且必須能夠接受 Type1 和 Type2 型別的所有值(可能是 const),無論其值類別如何(因此,不允許 Type1 &,C++11 起也不允許 Type1,除非對於 Type1,移動等效於複製)。
型別 Type1 和 Type2 必須使得 InputIt1 和 InputIt2 型別的物件可以被解引用,然後分別隱式轉換為 Type1 和 Type2。​

型別要求
-
InputIt1, InputIt2 必須滿足 LegacyInputIterator 的要求。
-
ForwardIt1, ForwardIt2 必須滿足 LegacyForwardIterator 的要求。
-
BinaryPred 必須滿足 BinaryPredicate 的要求。

[edit] 返回值

1-4) 如果兩個範圍中的每個相應元素都相等,則返回 true。否則返回 false。
5-8) 如果 std::distance(first1, last1) 和 std::distance(first2, last2) 相等,並且兩個範圍中的每個相應元素都相等,則返回 true。否則返回 false。

[edit] 複雜度

給定 N1 為 std::distance(first1, last1) 且 N2 為 std::distance(first2, last2)

1) 最多 N1 次使用 operator== 的比較。
2) O(N1) 次使用 operator== 的比較。
3) 最多 N1 次謂詞 p 的應用。
4) O(N1) 次謂詞 p 的應用。
5-8) 如果 InputIt1 和 InputIt2 都是 LegacyRandomAccessIterator,並且 last1 - first1 != last2 - first2 為 true,則不會進行比較。
否則,給定 N 為 min(N1,N2)
5) 最多 N 次使用 operator== 的比較。
6) O(N) 次使用 operator== 的比較。
7) 最多 N 次謂詞 p 的應用。
8) O(N) 次謂詞 p 的應用。

[edit] 異常

帶有模板引數 ExecutionPolicy 的過載按如下方式報告錯誤

  • 如果作為演算法一部分呼叫的函式執行丟擲異常,並且 ExecutionPolicy 是標準策略之一,則呼叫 std::terminate。對於任何其他 ExecutionPolicy,行為是實現定義的。
  • 如果演算法未能分配記憶體,則丟擲 std::bad_alloc

[edit] 可能的實現

equal (1)
template<class InputIt1, class InputIt2>
constexpr //< since C++20
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
{
    for (; first1 != last1; ++first1, ++first2)
        if (!(*first1 == *first2))
            return false;
 
    return true;
}
equal (3)
template<class InputIt1, class InputIt2, class BinaryPred>
constexpr //< since C++20
bool equal(InputIt1 first1, InputIt1 last1,
           InputIt2 first2, BinaryPred p)
{
    for (; first1 != last1; ++first1, ++first2)
        if (!p(*first1, *first2))
            return false;
 
    return true;
}
equal (5)
namespace detail
{
    // random-access iterator implementation (allows quick range size detection)
    template<class RandomIt1, class RandomIt2>
    constexpr //< since C++20
    bool equal(RandomIt1 first1, RandomIt1 last1, RandomIt2 first2, RandomIt2 last2,
               std::random_access_iterator_tag, std::random_access_iterator_tag)
    {
        if (last1 - first1 != last2 - first2)
            return false;
 
        for (; first1 != last1; ++first1, ++first2)
            if (!(*first1 == *first2))
                return false;
 
        return true;
    }
 
    // input iterator implementation (needs to manually compare with “last2”)
    template<class InputIt1, class InputIt2>
    constexpr //< since C++20
    bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
               std::input_iterator_tag, std::input_iterator_tag)
    {
        for (; first1 != last1 && first2 != last2; ++first1, ++first2)
            if (!(*first1 == *first2))
                return false;
 
        return first1 == last1 && first2 == last2;
    }
}
 
template<class InputIt1, class InputIt2>
constexpr //< since C++20
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
{
    details::equal(first1, last1, first2, last2,
                   typename std::iterator_traits<InputIt1>::iterator_category(),
                   typename std::iterator_traits<InputIt2>::iterator_category());
}
equal (7)
namespace detail
{
    // random-access iterator implementation (allows quick range size detection)
    template<class RandomIt1, class RandomIt2, class BinaryPred>
    constexpr //< since C++20
    bool equal(RandomIt1 first1, RandomIt1 last1,
               RandomIt2 first2, RandomIt2 last2, BinaryPred p,
               std::random_access_iterator_tag, std::random_access_iterator_tag)
    {
        if (last1 - first1 != last2 - first2)
            return false;
 
        for (; first1 != last1; ++first1, ++first2)
            if (!p(*first1, *first2))
                return false;
 
        return true;
    }
 
    // input iterator implementation (needs to manually compare with “last2”)
    template<class InputIt1, class InputIt2, class BinaryPred>
    constexpr //< since C++20
    bool equal(InputIt1 first1, InputIt1 last1,
               InputIt2 first2, InputIt2 last2, BinaryPred p,
               std::input_iterator_tag, std::input_iterator_tag)
    {
        for (; first1 != last1 && first2 != last2; ++first1, ++first2)
            if (!p(*first1, *first2))
                return false;
 
        return first1 == last1 && first2 == last2;
    }
}
 
template<class InputIt1, class InputIt2, class BinaryPred>
constexpr //< since C++20
bool equal(InputIt1 first1, InputIt1 last1,
           InputIt2 first2, InputIt2 last2, BinaryPred p)
{
    details::equal(first1, last1, first2, last2, p,
                   typename std::iterator_traits<InputIt1>::iterator_category(),
                   typename std::iterator_traits<InputIt2>::iterator_category());
}

[edit] 注意

std::equal 不應用於比較由 std::unordered_set、std::unordered_multiset、std::unordered_map 或 std::unordered_multimap 的迭代器形成的範圍,因為即使兩個容器儲存相同的元素,這些容器中元素的儲存順序也可能不同。

當比較整個容器或字串檢視的相等性時,通常首選相應型別的 operator==(C++17 起)。

順序 std::equal 不保證短路。例如,如果兩個範圍的第一個元素對不相等,其餘元素也可能被比較。當範圍與 std::memcmp 或實現特定的向量化演算法進行比較時,可能會發生非短路比較。

[edit] 示例

以下程式碼使用 std::equal 測試字串是否為迴文。

#include <algorithm>
#include <iomanip>
#include <iostream>
#include <string_view>
 
constexpr bool is_palindrome(const std::string_view& s)
{
    return std::equal(s.cbegin(), s.cbegin() + s.size() / 2, s.crbegin());
}
 
void test(const std::string_view& s)
{
    std::cout << std::quoted(s)
              << (is_palindrome(s) ? " is" : " is not")
              << " a palindrome\n";
}
 
int main()
{
    test("radar");
    test("hello");
}

輸出

"radar" is a palindrome
"hello" is not a palindrome

[edit] 另請參閱

尋找第一個滿足特定條件的元素
(函式模板) [編輯]
如果一個範圍在字典上小於另一個範圍,則返回 true
(函式模板) [編輯]
尋找兩個範圍開始不同的第一個位置
(函式模板) [編輯]
搜尋一個範圍的元素首次出現的位置
(函式模板) [編輯]
判斷兩組元素是否相同
(演算法函式物件)[編輯]
實現 x == y 的函式物件
(類模板) [編輯]
返回與特定鍵匹配的元素範圍
(函式模板) [編輯]