展平迭代器
是否有任何现有的迭代器实现(可能在 boost 中)可以实现某种扁平化迭代器?
例如:
unordered_set<vector<int> > s;
s.insert(vector<int>());
s.insert({1,2,3,4,5});
s.insert({6,7,8});
s.insert({9,10,11,12});
flattening_iterator<unordered_set<vector<int> >::iterator> it( ... ), end( ... );
for(; it != end; ++it)
{
cout << *it << endl;
}
//would print the numbers 1 through 12
Is there any existing iterator implementation (perhaps in boost) which implement some sort of flattening iterator?
For example:
unordered_set<vector<int> > s;
s.insert(vector<int>());
s.insert({1,2,3,4,5});
s.insert({6,7,8});
s.insert({9,10,11,12});
flattening_iterator<unordered_set<vector<int> >::iterator> it( ... ), end( ... );
for(; it != end; ++it)
{
cout << *it << endl;
}
//would print the numbers 1 through 12
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我不知道主要库中有任何实现,但它看起来像一个有趣的问题,所以我编写了一个基本的实现。我只用这里提供的测试用例对其进行了测试,因此我不建议在没有进一步测试的情况下使用它。
这个问题比看起来有点棘手,因为一些“内部”容器可能是空的,你必须跳过它们。这意味着将
flattening_iterator
前进一个位置实际上可能会将迭代器前进到“外部”容器中不止一个位置。因此,flattening_iterator
需要知道外部范围的末尾在哪里,以便知道何时需要停止。这个实现是一个前向迭代器。双向迭代器还需要跟踪外部范围的开头。
flatten
函数模板用于使构造flattening_iterator
变得更容易。以下是一个最小的测试存根:
就像我在开始时所说的那样,我还没有对此进行彻底的测试。如果您发现任何错误,请告诉我,我很乐意纠正它们。
I don't know of any implementation in a major library, but it looked like an interesting problem so I wrote a basic implementation. I've only tested it with the test case I present here, so I don't recommend using it without further testing.
The problem is a bit trickier than it looks because some of the "inner" containers may be empty and you have to skip over them. This means that advancing the
flattening_iterator
by one position may actually advance the iterator into the "outer" container by more than one position. Because of this, theflattening_iterator
needs to know where the end of the outer range is so that it knows when it needs to stop.This implementation is a forward iterator. A bidirectional iterator would also need to keep track of the beginning of the outer range. The
flatten
function templates are used to make constructingflattening_iterator
s a bit easier.The following is a minimal test stub:
Like I said at the beginning, I haven't tested this thoroughly. Let me know if you find any bugs and I'll be happy to correct them.
我决定对展平迭代器的概念进行一些“改进”,尽管正如 James 所指出的,您只能使用范围(最内部的容器除外),所以我只是彻底使用范围,从而获得了展平范围,具有任意深度。
首先我使用了一个积木:
然后定义了一个(非常小的)
ForwardRange
概念:这是我们的积木,尽管事实上我们可以用剩下的来凑合:
显然,它有效
I decided to "improve" a bit on the flattening iterator concept, though as noted by James you are stuck using Ranges (except for the inner most container), so I just used ranges through and through and thus obtained a flattened range, with an arbitrary depth.
First I used a building brick:
And then defined a (very minimal)
ForwardRange
concept:This is our building brick here, though in fact we could make do with just the rest:
And apparently, it works
我到达这里有点晚了,但我刚刚发布了 一个库 (multidim) 来处理此类问题。用法非常简单:使用您的示例,
该库仅包含标头并且没有依赖项。但需要 C++11。
I arrive a little late here, but I have just published a library (multidim) to deal with such problem. The usage is quite simple: to use your example,
The library is header-only and has no dependencies. Requires C++11 though.
您可以使用 boost 中的迭代器外观来制作一个。
我编写了迭代器产品,您也许可以将其用作模板:
http://code.google。 com/p/asadchev/source/browse/trunk/work/cxx/iterator/product.hpp
you can make one using iterator facade in boost.
I wrote iterator product which you can use as a template perhaps:
http://code.google.com/p/asadchev/source/browse/trunk/work/cxx/iterator/product.hpp
除了Matthieu的答案之外,您还可以自动计算可迭代/容器的维度数量。但首先,当某些东西是可迭代/容器时,我们必须设置一个规则:
我们可以按如下方式计算维度:
然后我们可以创建一个视图包装器,其中包含
begin()
和end ()
函数。为了使对象
Flatten
的创建变得更容易一些,我们定义了一个辅助函数:用法:
In addition to the answer of Matthieu, you can automatically count the amount of dimensions of the iterable/container. But first we must set up a rule when something is an iterable/container:
We can count the dimensions as follows:
We then can create a view wrapper, that contains a
begin()
andend()
function.To make the creation of the object
Flatten
a bit easier, we define a helper function:Usage: