上一节我们学习了比较算法equal()函数,读者是否还记得它的功能是什么吗?没错,它能够帮助我们快速比较两个序列。本节我们将学习新的比较算法——mismatch()函数。“mis”表示“否定”,“match”表示“匹配”,与equal()函数的功能不同,mismatch()函数不仅能判断两个序列是否相等,它还能找出第一个不相同的元素在哪。
mismatch()函数的语法格式为:
// 形式1:基本比较 template< class InputIt1, class InputIt2 > std::pair<InputIt1, InputIt2> mismatch( InputIt1 first1, InputIt1 last1, InputIt2 first2 ); // 形式2:使用自定义比较函数 template< class InputIt1, class InputIt2, class BinaryPredicate > std::pair<InputIt1, InputIt2> mismatch( InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p ); // 形式3:安全范围比较(C++14) template< class InputIt1, class InputIt2 > std::pair<InputIt1, InputIt2> mismatch( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2 ); // 形式4:安全范围+自定义比较(C++14) template< class InputIt1, class InputIt2, class BinaryPredicate > std::pair<InputIt1, InputIt2> mismatch( InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, BinaryPredicate p );
mismatch(first1, last1, first2, last2)指的是绝对比较区间[first1, last1)和[first2, last2)的各个元素,有返回值,返回类型为pair<iterator,iterator>,如果完全相等(满足二元谓词比较规则)则返回{last1,last2},否则返回{指向第一个序列不相等元素的迭代器,指向第二个序列不相等元素的迭代器}。
一眼我们就能发现一个问题,为什么mismatch()函数的第二个序列参数既可以是起始迭代器又可以是(起始迭代器+尾后迭代器)?原因有2:
第一个原因是由于最早使用mismatch()函数时默认第二个序列长度大于第一个序列,程序员习惯了这个参数形式。
第二个原因是由于数组越界问题会引发程序崩溃,所以决定第二个序列参数为起始迭代器+尾后迭代器,强调避免越界行为。
为了养成好习惯,我们尽量使用第二个版本,补齐第二个序列的尾后迭代器。但是笔者的编译器不支持第二个版本,考虑到兼容性,我们使用第一个版本来进行两个序列的比较,并找出两个序列不相等的元素。
#include<iostream>
#include<vector>
#include<functional>
#include<cmath>
#include<algorithm>
using namespace std;
/*普通函数&&判断误差在[0,1]之间都相等*/
bool pred(const float&f1,const float&f2)
{
return abs(f1-f2)<=1.0f;
}
/*mismatch(first1,last1,first2)*/
void test1() {
vector<int> v1{1, 2, 3, 4, 5};
vector<int> v2{1, 2, 9, 4, 5};
cout << "序列1为:";
for(auto it = v1.begin(); it != v1.end(); ++it) cout << *it << " ";
cout << '\n';
cout << "序列2为:";
for(auto it = v2.begin(); it != v2.end(); ++it) cout << *it << " ";
cout << '\n';
pair<vector<int>::iterator,vector<int>::iterator> p=mismatch(v1.begin(),v1.end(),v2.begin());
if(p.first!=v1.end()&&p.second!=v2.end())
{
cout << "通过mismatch()函数判断两个序列并不完全相等!\n";
cout << "序列1的不等元素为【" << *p.first<< "】\n";
cout << "序列2的不等元素为【" << *p.second<< "】\n\n";
}
}
/*mismatch(first1,last1,first2,pred)*/
/*通过二元谓词进行模糊查找*/
void test2() {
vector<float> v1{1.1, 2.2, 3.9, 4.4, 5.5};
vector<float> v2{1.2, 2.3, 2.5, 4.5, 5.6};
cout << "序列1为:";
for(auto it = v1.begin(); it != v1.end(); ++it) cout << *it << " ";
cout << '\n';
cout << "序列2为:";
for(auto it = v2.begin(); it != v2.end(); ++it) cout << *it << " ";
cout << '\n';
pair<vector<float>::iterator,vector<float>::iterator> p=mismatch(v1.begin(),v1.end(),v2.begin(),pred);
if(p.first!=v1.end()&&p.second!=v2.end())
{
cout << "通过mismatch()函数判断两个序列并不完全相等!\n";
cout << "序列1的不等元素为【" << *p.first<< "】\n";
cout << "序列2的不等元素为【" << *p.second<< "】\n";
}
}
int main(){
system("title dotcpp.com");
test1();
test2();
return 0;
}编译结果如下:

基于绝对比较规则,我们找到序列1中的“3”和序列2中的“9”不匹配;基于模糊比较,我们找到序列1中的“3.9”和序列2中的“2.5”不匹配。输出完全符合预期!
总结:当我们不仅仅是判断两个序列是否完全相等,在不等的情况下,我们还需要找出哪一对元素不相等,我们就需要使用mismatch()函数进行查找;同时,在蓝桥杯、ACM等算法竞赛上该函数主要运用于答案判断、最长公共前缀问题和序列差异分析等。
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程