You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

既然可使用std::find_if_not算法,为什么还需要std::partition_point?

std::partition_point 与 std::find_if_not 的核心区别

二者虽然在你给出的已划分序列场景下输出一致,但本质是完全不同的工具,差异主要有三点:

  • 前置要求不同
    std::partition_point有严格的前置条件:输入序列必须已经按照给定谓词完成划分,也就是所有满足pred的元素全部排在序列前半段,所有不满足pred的元素全部排在后半段。你测试用的样例刚好符合这个要求:前7个元素都是奇数(满足x%2为真),后面都是偶数,所以二者输出一致。
    而std::find_if_not没有任何序列有序/划分的前置要求,任意乱序序列都可以正常使用,返回第一个不满足谓词的元素。
    如果你的序列没有提前做划分,比如把测试向量改成{1,2,3,4},这时候调用partition_point属于未定义行为,返回结果完全不可预期,而find_if_not会正确返回指向第二个元素2的迭代器。
  • 时间复杂度差异极大
    std::partition_point基于二分查找实现:
    对于随机访问迭代器(比如std::vector、std::array的迭代器),时间复杂度为O(log n),最多仅需要执行log2(n) + 1次谓词判断;即使是前向迭代器,谓词判断的次数依然是O(log n),仅迭代移动次数为O(n)。
    而std::find_if_not是线性遍历实现,最坏情况需要遍历整个序列,执行*O(n)*次谓词判断。如果是处理长度为100万的已划分序列,partition_point只需要做20次左右的谓词判断就可以找到边界,find_if_not最坏要跑100万次,性能差了5个量级。
  • 适用场景不同
    std::partition_point是专门搭配划分类算法使用的工具:当你用std::partition、std::stable_partition对序列完成划分后,要快速获取划分边界的时候用它最合适。
    而std::find_if_not适用于任意无序序列,查找第一个不符合谓词的元素的场景。

补充验证代码(未划分序列下的差异)

#include <vector>
#include <iostream>
#include <algorithm>

template <typename In_It, typename FUNC>
In_It partitionPoint(In_It b, In_It e, FUNC pred){
    int len = e - b;
    while (len > 0){
        int half = len >> 1;
        In_It middle = b + half;
        if( pred(*middle) ){
            b = middle;
            ++b;
            len = len - half - 1;
        }
        else
            len = half;
    }
    return b;
}

int main(){
    // 未划分的序列:奇数偶数交替出现
    std::vector<int> v{1,2,3,4,5,6};
    auto pred = [](int x){return x % 2; };
    auto it_part = partitionPoint(v.begin(), v.end(), pred);
    auto it_find = std::find_if_not(v.begin(), v.end(), pred);

    std::cout << "partition_point返回结果:下标" << it_part - v.begin() << '\n';
    std::cout << "find_if_not返回结果:下标" << it_find - v.begin() << ",值为" << *it_find << '\n';
}

输出样例:

partition_point返回结果:下标6(越界,结果未定义)
find_if_not返回结果:下标1,值为2

内容的提问来源于stack exchange,提问作者Itachi Uchiwa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 00:27:03