C++ equal(STL equal)比较算法详解

2年前 (2024-04-28)
可以用和比较字符串类似的方式来比较序列。如果两个序列的长度相同,并且对应元素都相等,equal() 算返回 true。有 4 个版本的 equal() 算法,其中两个用 == 运算符来比较元素,另外两个用我们提供的作为参数的函数对象来比较元素,所有指定序列的迭代器都必须少是输入迭代器。

用 == 运算符来比较两个序列的个版本期望 3 个输入迭代器参数,前两个参数是个序列的开始和结束迭代器,第三个参数是第二个序列的开始迭代器。如果第二个序列中包含的元素少于个序列,结果是未定义的。用 == 运算符的第二个版本期望 4 个参数:个序列的开始和结束迭代器,第二个序列的开始和结束迭代器,如果两个序列的长度不同,那么结果总是为 false。本节会演示这两个版本,但使用接受 4 个参数的版本,因为它不会产生未定义的行为。

下面是一个演示如何应用它们的示例:

// Using the equal() algorithm

#include <iostream> // For standard streams

#include <vector> // For vector container

#include <algorithm> // For equal() algorithm

#include <iterator> // For stream iterators

#include <string> // For string class

using std::string;

int main()

{

std::vector<string> words1 {"one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};

std::vector<string> words2 {"two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"};

auto iter1 = std::begin(words1);

auto end_iter1 = std::end(words1);

auto iter2 = std::begin(words2);

auto end_iter2 = std::end(words2);

std::cout << "Container - words1:";

std::copy(iter1, end_iter1, std::ostream_iterator<string>{std::cout, " "});

std::cout << "\nContainer - words2:";

std::copy(iter2, end_iter2, std::ostream_iterator<string>{std::cout, " "});

std::cout << std::endl;

std::cout << "\n1. Compare from words1[1] to end with words2:";

std::cout << std::boolalpha << std::equal(iter1 + 1, end_iter1, iter2) << std::endl;

std::cout << "2. Compare from words2[0] to second-to-last with words1:";

std::cout << std::boolalpha << std::equal(iter2, end_iter2 - 1, iter1) << std::endl;

std::cout << "3. Compare from words1[1] to words1[5] with words2:";

std::cout << std::boolalpha << std::equal(iter1 + 1, iter1 + 6, iter2) << std::endl;

std::cout << "4. Compare first 6 from words1 with first 6 in words2:";

std::cout << std::boolalpha << std::equal(iter1, iter1 + 6, iter2, iter2 + 6) << std::endl;

std::cout << "5. Compare all words1 with words2:";

std::cout << std::boolalpha << std::equal(iter1, end_iter1, iter2) << std::endl;

std::cout << "6. Compare all of words1 with all of words2:";

std::cout << std::boolalpha << std::equal(iter1, end_iter1, iter2, end_iter2) << std::endl;

std::cout << "7. Compare from words1[1] to end with words2 from first to second-to-last:";

std::cout << std::boolalpha << std::equal(iter1 + 1, end_iter1, iter2, end_iter2 - 1) << std::endl;

}

输出结果为:

Container - words1: one two three four five six seven eight nine
Container - words2: two three four five six seven eight nine ten
网站站点" rel="nofollow" />

std::cout << std::boolalpha << (words1 == words2) << " "; // false

这两个版本的 equal() 接受一个谓词作为额外的参数。这个谓词定义了元素之间的等价 比较。下面是一个说明它们用法的代码段:

std::vector<string> r1 { "three", "two", "ten"};

std::vector<string> r2 {"twelve", "ten", "twenty" };

std::cout << std::boolalpha<< std::equal (std::begin (r1) , std::end (r1) , std::begin (r2),[](const string& s1, const string& s2) { return s1[0] = s2[0]; })<< std::endl; // true

std::cout << std::boolalpha<<std::equal(std::begin(r1), std::end(r1), std::begin(r2), std::end(r2),[](const string& s1, const string& s2) { return s1[0] == s2[0]; }) << std::endl; // true

在 equal() 的次使用中,第二个序列是由开始迭代器指定的。谓词是一个在字符串 参数的个字符相等时返回 true 的 lambda 表达式。一条语句表明,equal() 算法可以使用两个全范围的序列,并使用相同的谓词。

不应该用 equal() 来比较来自于无序 map 或 set 容器中的元素序列。在无序容器中,一组给定元素的顺序可能和保存在另一个无序容器中的一组相等元素不同,因为不同容器的元素很可能会被分配到不同的格子中。