泛型算法——只读算法(二)

equal

在 C++ 标准库中,std::equal是一个泛型算法,用于比较两个序列(范围)中的元素是否相等。
  1. 函数原型
template <class InputIt1, class InputIt2>
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2);

template <class InputIt1, class InputIt2, class BinaryPredicate>
bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2, BinaryPredicate p);

参数
● first1, last1:第一个序列的范围 [first1, last1)。
● first2:第二个序列的起始位置。
● p:自定义的二元谓词(可选),用于定义“相等”的条件。

返回值
● true:如果两个序列在指定范围内相等。
● false:否则。

  1. 示例代码:基础比较(默认相等条件)
#include <algorithm>
#include <vector>
#include <iostream>

int main() {
    std::vector<int> v1 = {1, 2, 3, 4, 5};
    std::vector<int> v2 = {1, 2, 3, 4, 5};
    std::vector<int> v3 = {1, 2, 3, 4, 6};

    // 比较整个范围是否相等
    bool same1 = std::equal(v1.begin(), v1.end(), v2.begin());
    bool same2 = std::equal(v1.begin(), v1.end(), v3.begin());

    std::cout << "v1 vs v2: " << std::boolalpha << same1 << std::endl; // 输出 true
    std::cout << "v1 vs v3: " << same2 << std::endl;                   // 输出 false

    return 0;
}
  1. 示例代码:自定义比较条件

比较两个序列是否满足自定义的“近似相等”条件(如浮点数误差允许范围内):

#include <algorithm>
#include <vector>
#include <cmath>

bool approxEqual(double a, double b) {
    return std::abs(a - b) < 0.001; // 允许误差小于 0.001
}

int main() {
    std::vector<double> a = {1.0, 2.0001, 3.0};
    std::vector<double> b = {1.0, 2.0, 3.0};

    bool isApprox = std::equal(a.begin(), a.end(), b.begin(), approxEqual);
    // 返回 true(2.0001 和 2.0 的差为 0.0001 < 0.001)

    return 0;
}
  1. 关键注意事项
第二个序列的长度必须足够
  • std::equal不会检查第二个序列的长度。若第二个序列短于第一个序列,会导致 未定义行为
  • 安全做法:比较前手动检查长度:
if (v1.size() != v2.size()) {
    return false;
}
bool same = std::equal(v1.begin(), v1.end(), v2.begin());
支持不同类型容器的比较
两个序列可以来自不同类型的容器(如vector和list),只要元素可比较:
std::vector<int> vec = {1, 2, 3};
std::list<int> lst = {1, 2, 3};
bool same = std::equal(vec.begin(), vec.end(), lst.begin()); // true
自定义谓词的要求
谓词 p 必须满足: p(a, b) 返回 bool,且不会修改传入的参数。 示例错误(修改元素):
// 错误:谓词不应有副作用
bool badPredicate(int& a, int& b) {
    a++; // 修改元素,导致未定义行为
    return a == b;
}
性能

● 时间复杂度:O(n),遍历所有元素直到发现不匹配或结束。
● 适用场景:中小型数据集的快速比较,或对性能不敏感的场景。

  1. 常见问题

Q1:如何比较两个完整容器(包括长度和内容)?

  • 直接比较容器(如果容器支持operator==)
if (v1 == v2) { /* ... */ } // vector/list/deque 等支持
  • 手动比较长度 + std::equal:
bool isSame = (v1.size() == v2.size()) 
              && std::equal(v1.begin(), v1.end(), v2.begin());

Q2:如何比较子范围?

  • 调整迭代器范围:
// 比较 v1 的前3个元素和 v2 的第2到第4个元素
bool same = std::equal(v1.begin(), v1.begin()+3, v2.begin()+1);
  • Q3:std::equal与 memcmp的区别?

● memcmp:按字节逐位比较,适用于 POD 类型(如基本类型、简单结构体),但 不适用于类对象(如 std::string)。
● std::equal:通过 operator== 或自定义谓词比较,适用于所有可比较类型。

  1. 总结

● 核心用途:快速比较两个序列的相等性,支持自定义比较逻辑。

● 安全要点:确保第二个序列足够长,避免未定义行为。
● 扩展性:通过自定义谓词,灵活定义“相等”条件。
合理使用 std::equal 可以简化代码并提高可读性,尤其适用于验证数据一致性(如测试用例)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

taciturn丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值