将迭代器作为 3 个元素的滑动窗口,可以超调边界(可能使用 Boost)
Having an iterator as a sliding window of 3 elements that can overshoot bounds (possibly using Boost)
阅读了这篇文章并探索了 Boost.Iterator,我想看看我是否可以让大小为 3 的滑动窗口迭代单个向量,其中最终迭代具有"空的第三个元素"。
假设向量大小为>= 2,举个例子:
{a, b, c, d, e, f, g}
我们将始终从索引 1 开始,因为我正在实现的这个算法需要一个"上一个"元素存在,并且不需要对第一个元素进行操作(因此我们将在i < size()
时从i = 1
迭代(:
V
[a, b, c]
{a, b, c, d, e, f, g}
当我移动到下一个迭代时,它看起来像:
V
[b, c, d]
{a, b, c, d, e, f, g}
在到达迭代中的最后一个元素时,它将具有以下内容:
V
[f, g, EMPTY]
{a, b, c, d, e, f, g}
我想要的是能够抓取"prev"并检查"hasNext"并获取下一个元素(如果可用(。我的目标是非常干净的现代C++代码,并且它不对三个不同元素的跟踪指针/引用进行簿记,使代码更加干净:
for (const auto& it : zippedIterator(dataVector)) {
someFunc(it.first, triplet.second);
if (someCondition(it.second) && hasThirdElement) {
anotherFunc(it.second, it.third)
}
}
我试图看看 boost 的 zip 迭代器是否可以做到这一点,但我不知道它是否允许我超调末端并有一些空值。
我想过做一些黑客的事情,比如有一个虚拟的最终元素,但随后我必须记录它,我正在尝试用零黑客技巧编写干净的代码。
我也打算推出我自己的迭代器,但显然 std::itrator 已被弃用。
我也不想创建底层向量的副本,因为这将用于需要快速的紧密循环中,并且复制所有内容对于底层对象来说将非常昂贵。它不需要非常优化,但将迭代器值复制到新数组是不可能的。
如果这只是一个范围的大小窗口的问题,那么你真正想要的是一个可以前进的范围。在您的情况下,该范围有 3 个元素长,但没有理由通用机制不允许可变大小的范围。它只是一对迭代器,这样你可以++或 - 同时使用它们。
您遇到的问题是,如果子范围不在范围的末尾,则要制造元素。这使事情复杂化;这将需要代理迭代器等等。
如果您想要针对特定情况的解决方案(3 元素大小的范围,如果最后一个元素不在主范围的末尾,则可以制造最后一个元素(,那么您首先需要决定是否要为此提供实际类型。也就是说,是否值得实现一个完整的类型,而不是几个一次性的实用程序函数?
我处理这个问题的方法是重新定义问题。您似乎拥有的是当前元素,就像任何其他迭代一样。但是您希望能够访问上一个元素。并且您希望能够向前窥视下一个元素;如果没有,那么你想制造一些默认值。所以。。。执行迭代,但编写几个实用程序函数,以便从当前元素访问所需的内容。
for(auto curr = ++dataVector.begin();
curr != dataVector.end();
++curr)
{
someFunc(prevElement(curr), *curr);
auto nextIt = curr + 1;
if(nextIt != dataVector.end() && someCondition(*curr))
anotherFunc(*curr, *nextIt)
}
prevElement
是一个简单的函数,它在给定迭代器之前访问元素。
template<typename It>
//requires BidirectionalIterator<It>
decltype(auto) prevElement(It curr) {return *(--curr);}
如果你想有一个函数来检查下一个元素并为它制造一个值,那也可以做到。这个必须返回元素的 prvalue,因为我们可能必须制造它:
template<typename It>
//requires ForwardIterator<It>
auto checkNextElement(It curr, It endIt)
{
++curr;
if(curr == endIt)
return std::iterator_traits<It>::value_type{};
return *curr;
}
是的,这并不全是聪明的,有特殊的范围类型等。但是你正在做的事情并不常见,尤其是你必须像你一样制造下一个元素。通过保持简单明了,您可以让某人轻松阅读您的代码,而无需了解某些专门的子范围类型。
- 理解boost::asio-async_read在无需读取内容时的行为
- boost::进程间消息队列引发错误
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- cmake如何在fedora工作站中找到boost静态库包
- CMake项目Boost库错误:Boost/config/compiler/gcc.hpp:165:10:致命错误:cs
- Boost Graph Library,修复节点大小
- 什么是"#include <boost/functional/hash.hpp> "?
- 基于boost的程序的静态链接——zlib问题
- C++:如何在CLion IDE中安装Boost
- C++Boost Asio Pool线程,带有lambda函数和传递引用变量
- 如何在boost beast http请求中设置http头
- Boost Spirit,获取迭代器内部语义动作
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- boost::asio如何生成多个协同程序,然后加入它们
- std::当在256字节边界上写入整数时,流的奇怪行为
- 当我尝试使用 sstream 和分面将 Boost Time_duration转换为字符串时,我没有得到所需的格式
- 将迭代器作为 3 个元素的滑动窗口,可以超调边界(可能使用 Boost)
- Boost R-Tree中的最小边界矩形计算
- 是否可以让boost语言环境边界分析在撇号上进行拆分
- 如何使用Boost.Log跨越DLL边界