Namespaces
Variants

std:: is_permutation

From cppreference.net
Algorithm library
Constrained algorithms and algorithms on ranges (C++20)
Constrained algorithms, e.g. ranges::copy , ranges::sort , ...
Execution policies (C++17)
Non-modifying sequence operations
Batch operations
(C++17)
Search operations
Modifying sequence operations
Copy operations
(C++11)
(C++11)
Swap operations
Transformation operations
Generation operations
Removing operations
Order-changing operations
(until C++17) (C++11)
(C++20) (C++20)
Sampling operations
(C++17)

Sorting and related operations
Partitioning operations
Sorting operations
Binary search operations
(on partitioned ranges)
Set operations (on sorted ranges)
Merge operations (on sorted ranges)
Heap operations
Minimum/maximum operations
Lexicographical comparison operations
Permutation operations
is_permutation
(C++11)


C library
Numeric operations
Operations on uninitialized memory
定义于头文件 <algorithm>
template < class ForwardIt1, class ForwardIt2 >

bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 first2 ) ;
(1) (C++11 起)
(C++20 起为 constexpr)
template < class ForwardIt1, class ForwardIt2,

class BinaryPredicate >
bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 first2, BinaryPredicate p ) ;
(2) (C++11 起)
(C++20 起为 constexpr)
template < class ForwardIt1, class ForwardIt2 >

bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,

ForwardIt2 first2, ForwardIt2 last2 ) ;
(3) (C++14 起)
(C++20 起为 constexpr)
template < class ForwardIt1, class ForwardIt2,

class BinaryPredicate >
bool is_permutation ( ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,

BinaryPredicate p ) ;
(4) (C++14 起)
(C++20 起为 constexpr)

检查 [ first1 , last1 ) 是否为由 first2 起始范围的 排列

  • 对于重载 (1,2) ,第二个范围包含 std:: distance ( first1, last1 ) 个元素。
  • 对于重载 (3,4) ,第二个范围是 [ first2 , last2 )
1,3) 元素使用 operator == 进行比较。
2,4) 使用给定的二元谓词 p 对元素进行比较。

如果 ForwardIt1 ForwardIt2 具有不同的 value types ,则程序行为未定义。

如果比较函数不是 等价关系 ,则行为未定义。

目录

参数

first1, last1 - 定义待比较第一个元素 范围 的迭代器对
first2, last2 - 定义待比较第二个元素 范围 的迭代器对
p - 二元谓词,若元素应被视为相等则返回​ true

谓词函数的签名应等价于如下形式:

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

虽然签名不必包含 const & ,但函数不得修改传递给它的对象,且必须能够接受所有(可能为 const 的) Type1 Type2 类型的值,无论其 值类别 为何(因此不允许 Type1 & ,也不允许 Type1 ,除非对于 Type1 移动等价于复制 (C++11 起) )。
类型 Type1 Type2 必须使得 InputIt1 InputIt2 类型的对象在解引用后能隐式转换到 Type1 Type2 respectively。 ​

类型要求
-
ForwardIt1, ForwardIt2 必须满足 LegacyForwardIterator 的要求。

返回值

当范围 [ first1 , last1 ) 是范围 [ first2 , last2 ) 的一个排列时返回 true ,否则返回 false

复杂度

给定 N std:: distance ( first1, last1 )

1) 若两个范围相等,则恰好进行 N operator == 比较;否则在最坏情况下进行 O(N 2
)
次比较。
2) 若两个范围相等,则谓词 p 恰好应用 N 次;否则在最坏情况下应用 O(N 2
)
次。
3,4) ForwardIt1 ForwardIt2 均为 LegacyRandomAccessIterator ,且 last1 - first1 ! = last2 - first2 true ,则不会进行任何比较。
否则:
3) 若两个范围相等,则恰好进行 N operator == 比较;否则在最坏情况下进行 O(N 2
)
次比较。
4) 若两个范围相等则精确应用谓词 p N 次,否则最坏情况下应用 O(N 2
)
次。

可能的实现

template<class ForwardIt1, class ForwardIt2>
bool is_permutation(ForwardIt1 first, ForwardIt1 last,
                    ForwardIt2 d_first)
{
    // 跳过公共前缀
    std::tie(first, d_first) = std::mismatch(first, last, d_first);
    // 遍历剩余部分,统计每个元素
    // 在 [first, last) 区间内出现在 [d_first, d_last) 区间中的次数
    if (first != last)
    {
        ForwardIt2 d_last = std::next(d_first, std::distance(first, last));
        for (ForwardIt1 i = first; i != last; ++i)
        {
            if (i != std::find(first, i, *i))
                continue; // 此 *i 已被检查
            auto m = std::count(d_first, d_last, *i);
            if (m == 0 || std::count(i, last, *i) != m)
                return false;
        }
    }
    return true;
}

注意

std::is_permutation 可用于 测试 场景,即检验重排算法(如排序、洗牌、分区)的正确性。若 x 是原始区间, y 是经过 排列 的区间,则 std :: is_permutation ( x, y ) == true 表示 y “相同” 元素组成,这些元素可能位于不同位置。

示例

#include <algorithm>
#include <iostream>
template<typename Os, typename V>
Os& operator<<(Os& os, const V& v)
{
    os << "{ ";
    for (const auto& e : v)
        os << e << ' ';
    return os << '}';
}
int main()
{
    static constexpr auto v1 = {1, 2, 3, 4, 5};
    static constexpr auto v2 = {3, 5, 4, 1, 2};
    static constexpr auto v3 = {3, 5, 4, 1, 1};
    std::cout << v2 << " is a permutation of " << v1 << ": " << std::boolalpha
              << std::is_permutation(v1.begin(), v1.end(), v2.begin()) << '\n'
              << v3 << " is a permutation of " << v1 << ": "
              << std::is_permutation(v1.begin(), v1.end(), v3.begin()) << '\n';
}

输出:

{ 3 5 4 1 2 } is a permutation of { 1 2 3 4 5 }: true
{ 3 5 4 1 1 } is a permutation of { 1 2 3 4 5 }: false

参见

生成元素范围的下一个较大字典序排列
(函数模板)
生成元素范围的下一个较小字典序排列
(函数模板)
指定 relation 施加等价关系
(概念)
判断序列是否为另一序列的排列
(算法函数对象)