一 概述
C++ 标准库中提供了很多算法,定义于头文件 < algorithm >。本文主要探究以下用于 区间比较 的算法:
equal 检验相等性 is_permutation(C++11) 测试不定序的相等性 mismatch 查找第一处不同 lexicographical_compare 字典次序比较
二 辅助函数
三 std::equal
template < class InputIt1 , class InputIt2 >
bool equal ( InputIt1 first1, InputIt1 last1, InputIt2 first2 ) ; ( until C++ 20 )
template < class InputIt1 , class InputIt2 >
bool equal ( InputIt1 first1, InputIt1 last1, InputIt2 first2,
InputIt2 last2 ) ; ( since C++ 14 ) ( until C++ 20 )
template < class ExecutionPolicy , class ForwardIt1 , class ForwardIt2 >
bool equal ( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1,
ForwardIt2 first2 ) ; ( since C++ 17 )
template < class ExecutionPolicy , class ForwardIt1 , class ForwardIt2 >
bool equal ( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2,
ForwardIt2 last2 ) ; ( since C++ 17 )
template < class InputIt1 , class InputIt2 , class BinaryPredicate >
bool equal ( InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p ) ; ( until C++ 20 )
template < class InputIt1 , class InputIt2 , class BinaryPredicate >
bool equal ( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
BinaryPredicate p ) ; ( since C++ 14 ) ( until C++ 20 )
template < class ExecutionPolicy , class ForwardIt1 , class ForwardIt2 , class BinaryPredicate >
bool equal ( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2,
BinaryPredicate p ) ; ( since C++ 17 )
template < class ExecutionPolicy , class ForwardIt1 , class ForwardIt2 , class BinaryPredicate >
bool equal ( ExecutionPolicy&& policy, ForwardIt1 first1, ForwardIt1 last1, ForwardIt2 first2,
ForwardIt2 last2, BinaryPredicate p ) ; ( since C++ 17 )
. . . . . .
std:: vector< int > vc1;
std:: vector< int > vc2;
std:: vector< int > vc3;
std:: vector< int > vc4;
fill ( vc1, 1 , 3 ) ;
fill ( vc2, 1 , 4 ) ;
fill ( vc3, 1 , 5 ) ;
fill ( vc4, 1 , 4 ) ;
print ( "vc1: " , vc1) ;
print ( "vc2: " , vc2) ;
print ( "vc3: " , vc3) ;
print ( "vc4: " , vc4) ;
std:: cout << "vc1 and vc2 is "
<< ( std:: equal ( vc1. begin ( ) , vc1. end ( ) , vc2. begin ( ) , vc2. end ( ) )
? "" : "not " ) << "equal." << std:: endl;
std:: cout << "vc2 and vc3 is "
<< ( std:: equal ( vc2. begin ( ) , vc2. end ( ) , vc3. begin ( ) )
? "" : "not " ) << "equal." << std:: endl;
std:: cout << "vc2 and vc3 is "
<< ( std:: equal ( vc2. begin ( ) , vc2. end ( ) , vc3. begin ( ) , vc3. end ( ) )
? "" : "not " ) << "equal." << std:: endl;
std:: cout << "vc2 and vc4 is "
<< ( std:: equal ( vc2. begin ( ) , vc2. end ( ) , vc4. begin ( ) , my_equal)
? "" : "not " ) << "equal." << std:: endl;
vc1: 1 2 3
vc2: 1 2 3 4
vc3: 1 2 3 4 5
vc4: 1 2 3 4
vc1 and vc2 is not equal.
vc2 and vc3 is equal.
vc2 and vc3 is not equal.
vc2 and vc4 is equal.
三 std::is_permutation(C++11)
两个区间是否具有相同的排列组合(permutation) 定义
is_permutation定义式包含以下几种形式:(类似 std::equal)
第1个区间以[begin,end)表示 第2个区间以begin 或者[begin,end)表示 增加模板参数 BinaryPredicate的形式 Demo
std:: vector< int > vc1{ 3 , 2 , 1 } ;
std:: vector< int > vc2;
std:: vector< int > vc3;
std:: vector< int > vc4{ 4 , 2 , 1 , 3 } ;
fill ( vc2, 1 , 4 ) ;
fill ( vc3, 1 , 5 ) ;
print ( "vc1: " , vc1) ;
print ( "vc2: " , vc2) ;
print ( "vc3: " , vc3) ;
print ( "vc4: " , vc4) ;
std:: cout << "vc1 and vc2 is "
<< ( std:: is_permutation ( vc1. begin ( ) , vc1. end ( ) , vc2. begin ( ) , vc2. end ( ) )
? "" : "not " ) << "equal." << std:: endl;
std:: cout << "vc2 and vc3 is "
<< ( std:: is_permutation ( vc2. begin ( ) , vc2. end ( ) , vc3. begin ( ) )
? "" : "not " ) << "equal." << std:: endl;
std:: cout << "vc2 and vc3 is "
<< ( std:: is_permutation ( vc2. begin ( ) , vc2. end ( ) , vc3. begin ( ) , vc3. end ( ) )
? "" : "not " ) << "equal." << std:: endl;
std:: cout << "vc3 and vc4 is "
<< ( std:: is_permutation ( vc2. begin ( ) , vc2. end ( ) , vc4. begin ( ) , my_equal)
? "" : "not " ) << "equal." << std:: endl;
vc1: 3 2 1
vc2: 1 2 3 4
vc3: 1 2 3 4 5
vc4: 4 2 1 3
vc1 and vc2 is not equal.
vc2 and vc3 is equal.
vc2 and vc3 is not equal.
vc3 and vc4 is equal.
说明
若第2区间仅以begin表示,则只比较到第1区间结尾为止,例如 “结果1”; 若第2区间以[begin,end)表示,则比较的是完整的第1区间和第2区间,例如 “结果2”; 注意第1区间长度不能大于第2区间;
四 std::mismatch
定义
mismatch定义式类似 std::equal 注意返回值为pair
template < class InputIt1 , class InputIt2 >
std:: pair< InputIt1, InputIt2>
mismatch ( InputIt1 first1, InputIt1 last1, InputIt2 first2 ) ;
std:: vector< int > vc1{ 3 , 2 , 1 } ;
std:: vector< int > vc2;
std:: vector< int > vc3;
std:: vector< int > vc4{ 4 , 2 , 1 , 3 } ;
fill ( vc2, 1 , 4 ) ;
fill ( vc3, 1 , 5 ) ;
print ( "vc1: " , vc1) ;
print ( "vc2: " , vc2) ;
print ( "vc3: " , vc3) ;
print ( "vc4: " , vc4) ;
auto pair1 = std:: mismatch ( vc1. begin ( ) , vc1. end ( ) , vc2. begin ( ) ) ;
std:: cout << "vc1 and vc2 mismatch: No." << std:: distance ( vc1. begin ( ) , pair1. first)
<< " : No." << std:: distance ( vc2. begin ( ) , pair1. second) << std:: endl;
auto pair11 = std:: mismatch ( vc1. begin ( ) , vc1. end ( ) , vc2. begin ( ) , my_equal) ;
std:: cout << "vc1 and vc2 mismatch: No."
<< std:: distance ( vc1. begin ( ) , pair11. first) << " : No."
<< std:: distance ( vc2. begin ( ) , pair11. second) << std:: endl;
auto pair2 = std:: mismatch ( vc2. begin ( ) , vc2. end ( ) , vc3. begin ( ) , vc3. end ( ) ) ;
std:: cout << "vc2 and vc3 mismatch: No."
<< std:: distance ( vc2. begin ( ) , pair2. first) << " : No."
<< std:: distance ( vc3. begin ( ) , pair2. second) << std:: endl;
auto pair22 = std:: mismatch ( vc2. begin ( ) , vc2. end ( ) , vc3. begin ( ) , vc3. end ( ) , my_equal) ;
std:: cout << "vc2 and vc3 mismatch: No."
<< std:: distance ( vc2. begin ( ) , pair22. first) << " : No."
<< std:: distance ( vc3. begin ( ) , pair22. second) << std:: endl;
auto pair3 = std:: mismatch ( vc3. begin ( ) , vc3. end ( ) , vc4. begin ( ) , vc4. end ( ) , my_equal) ;
std:: cout << "vc3 and vc4 mismatch: No."
<< std:: distance ( vc3. begin ( ) , pair3. first) << " : No."
<< std:: distance ( vc4. begin ( ) , pair3. second) << std:: endl;
auto pair4 = std:: mismatch ( vc3. begin ( ) , vc3. end ( ) , vc2. begin ( ) , vc2. end ( ) , my_equal) ;
std:: cout << "vc3 and vc2 mismatch: No."
<< std:: distance ( vc3. begin ( ) , pair4. first) << " : No."
<< std:: distance ( vc2. begin ( ) , pair4. second) << std:: endl;
vc1: 3 2 1
vc2: 1 2 3 4
vc3: 1 2 3 4 5
vc4: 4 2 1 3
vc1 and vc2 mismatch: No. 0 : No. 0
vc1 and vc2 mismatch: No. 0 : No. 0
vc2 and vc3 mismatch: No. 4 : No. 4
vc2 and vc3 mismatch: No. 4 : No. 4
vc3 and vc4 mismatch: No. 0 : No. 0
vc3 and vc2 mismatch: No. 4 : No. 4
说明
结果1和2说明对区间长度没有要求(demo 为windows下运行)。没有不同,则较短区间返回end()和另一序列对应元素迭代器组成pair返回。 没有找到不同,不代表区间相同,例如结果1, vc3比vc2元素多。
五 std::lexicographical_compare
lexicographical:字典次序 定义
lexicographical_compare定义式包含以下几种形式:(类似 std::equal)
第1个区间以[begin,end)表示 第2个区间以 [begin,end) 表示 增加模板参数 ExecutionPolicy 增加模板参数 Compare 增加模板参数 ExecutionPolicy 和 Compare Demo
std:: vector< int > vc1{ 3 , 2 , 1 } ;
std:: vector< int > vc2;
std:: vector< int > vc3;
std:: vector< int > vc4{ 4 , 2 , 1 , 3 } ;
fill ( vc2, 1 , 4 ) ;
fill ( vc3, 1 , 5 ) ;
print ( "vc1: " , vc1) ;
print ( "vc2: " , vc2) ;
print ( "vc3: " , vc3) ;
print ( "vc4: " , vc4) ;
std:: cout << "vc1 lexicographical "
<< ( std:: lexicographical_compare ( vc1. begin ( ) , vc1. end ( ) , vc2. begin ( ) , vc2. end ( ) )
? "" : "not " ) << "less than vc2 ." << std:: endl;
std:: cout << "vc2 lexicographical "
<< ( std:: lexicographical_compare ( vc2. begin ( ) , vc2. end ( ) ,
vc3. begin ( ) , vc3. end ( ) , std:: greater< int > ( ) )
? "" : "not " ) << "less than vc3 ." << std:: endl;
std:: cout << "vc3 lexicographical "
<< ( std:: lexicographical_compare ( vc3. begin ( ) , vc3. end ( ) , vc2. begin ( ) , vc2. end ( ) ,
std:: greater< int > ( ) )
? "" : "not " ) << "less than vc2 ." << std:: endl;
std:: cout << "vc3 lexicographical "
<< ( std:: lexicographical_compare ( vc3. begin ( ) , vc3. end ( ) , vc4. begin ( ) , vc4. end ( ) ,
std:: greater< int > ( ) )
? "" : "not " ) << "less than vc4 ." << std:: endl;
vc1: 3 2 1
vc2: 1 2 3 4
vc3: 1 2 3 4 5
vc4: 4 2 1 3
vc1 lexicographical not less than vc2 .
vc2 lexicographical less than vc3 .
vc3 lexicographical not less than vc2 .
vc3 lexicographical not less than vc4 .
说明
结果1和2说明对区间长度没有要求(demo 为windows下运行)。 共有的元素都相等,则元素数少的区间小于另一序列,例如 “结果1”。
六 参考