std::is_permutation
| 定义于头文件 <algorithm>
|
||
template< class ForwardIt1, class ForwardIt2 >
bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2 );
|
(1) | (自C++11起) (constexpr 自C++20起) |
template< class ForwardIt1, class ForwardIt2,
class BinaryPredicate >
bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, BinaryPredicate p );
|
(2) | (自C++11起) (constexpr 自C++20起) |
template< class ForwardIt1, class ForwardIt2 >
bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2 );
|
(3) | (自C++14起) (constexpr 自C++20起) |
template< class ForwardIt1, class ForwardIt2,
class BinaryPredicate >
bool is_permutation( ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2, ForwardIt2 last2,
BinaryPredicate p );
|
(4) | (自C++14起) (constexpr 自C++20起) |
检查 [first1, last1) 是否是一个 排列 的范围始于 first2:
- 对于重载 (1,2),第二个范围包含
std::distance(first1, last1)个元素。 - 对于重载 (3,4),第二个范围是
[first2,last2)。
operator== 进行比较。p 进行比较。如果 ForwardIt1 和 ForwardIt2 具有不同的 值类型,则程序非良构。
如果比较函数不是一个 等价关系,则行为未定义。
参数
| first1, last1 | - | 定义待比较第一个元素 范围 的迭代器对 |
| first2, last2 | - | 定义待比较第二个元素 范围 的迭代器对 |
| p | - |
二元谓词,若元素应被视为相等则返回
true
谓词函数的签名应等价于如下形式: bool pred ( const Type1 & a, const Type2 & b ) ;
虽然签名不必包含
const
&
,但函数不得修改传递给它的对象,且必须能够接受所有(可能为 const 的)
|
| 类型要求 | ||
-
ForwardIt1, ForwardIt2
必须满足
LegacyForwardIterator
的要求。
|
||
返回值
当范围
[
first1
,
last1
)
是范围
[
first2
,
last2
)
的一个排列时返回
true
,否则返回
false
。
复杂度
给定N作为std::distance(first1, last1):
operator==如果两个范围相等,否则O(N2)次比较在最坏情况下。
p如果两个范围相等,否则O(N2)次应用在最坏情况下。
ForwardIt1和ForwardIt2都是LegacyRandomAccessIterator,并且last1 - first1 != last2 - first2是true,则不进行比较。operator==如果两个范围相等,否则O(N2)次比较在最坏情况下。
p如果两个范围相等,否则O(N2)次应用在最坏情况下。
可能的实现
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
另见
| 生成元素范围的下一个按字典序更大的排列 (函数模板 & 算法函数对象) | |
(C++20) |
|
| 生成元素范围的下一个按字典序更小的排列 (函数模板 & 算法函数对象) | |
(C++20) |
|
(C++20) |
指定一个 关系 构成等价关系 (概念) |
(C++20) |
确定一个序列是否为另一个序列的排列 (算法函数对象) |