上一节我们学习了比较算法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;
}

编译结果如下:

mismatch()函数

基于绝对比较规则,我们找到序列1中的“3”和序列2中的“9”不匹配;基于模糊比较,我们找到序列1中的“3.9”和序列2中的“2.5”不匹配。输出完全符合预期!

总结:当我们不仅仅是判断两个序列是否完全相等,在不等的情况下,我们还需要找出哪一对元素不相等,我们就需要使用mismatch()函数进行查找;同时,在蓝桥杯、ACM等算法竞赛上该函数主要运用于答案判断、最长公共前缀问题和序列差异分析等。

点赞(0)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)