c++ - 为什么我们需要 std::partition_point 而我们可以使用 std::find_if_not 算法?
问题描述
这是我可能的算法实现std::partition_point
是:
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;
}
我的代码看起来像 STL,除了使用std::distance
, traits
... 所以它检查输入序列并返回一个迭代器到谓词成功的序列中的最后一个元素。换句话说,返回的迭代器表示一个不满足谓词的元素。
int main(){
std::vector<int> v{1, 3, 5, 7, 9, 1, 3, 6, 8, 10, 12};
auto it = partitionPoint(v.begin(), v.end(), [](int x){return x % 2; });
if( it != v.cend() )
std::cout << *it << " " << it - v.cbegin() << '\n';
}
输出:
6 at index: 7
没关系。但是为什么我不直接使用std::find_if_not
它将迭代器返回到谓词为假的第一个元素?
auto it2 = findIfNot(v.cbegin(), v.cend(), [](int x){return x % 2; });
if(it2 != v.cend())
std::cout << *it2 << " at index: " << it2 - v.cbegin() << '\n';
输出:
6 at index: 7
解决方案
std::find_if_not
具有O(N)
复杂性,因为它进行线性遍历。 std::partition_point
另一方面具有O(logN)
复杂性,因为它利用了集合被分区并进行二进制搜索以找到元素的事实。根据情况,这可能是一个巨大的性能胜利。
推荐阅读
- django - 如何在 django 中指定lookup_field
- javascript - 如何获取旧值和新值并进行比较
- amazon-web-services - 面向用户的网站的 S3 存储桶策略
- swift - 我通过在scenekit中连接线来绘制一个矩形或任何形状,我如何将它转换为SCNNode或仅在指定形状内应用纹理
- firebase - 动态创建 Firebase 项目
- reactjs - 将 @babel/plugin-proposal-class-properties (https://git.io/vb4SL) 添加到 Babel 配置的“插件”部分以启用转换
- c# - 即使在登录到应用程序后,也无法在 Asp.NET Core Razor 视图中显示当前登录用户的详细信息
- c++ - 如何建立或附加控制台到在 Linux 上运行的 c++ 应用程序以进行用户交互,如输入输出
- node.js - 来自 chokidar 的错误:错误:未知:未知错误,请观看
- html - 如何让猫头鹰旋转木马垂直滑动???在演示中,只有水平滑动。我想垂直定制它