如何解决2 个范围的所有组合的迭代器
是否可以使用 boost::iterators 库来创建显示 2 个范围组合结果的迭代器?请注意,为了使用,我们需要输出是迭代器。我们也不期望首先手动创建所有组合的向量。 (注:我们用C++17编译)
一个人为的例子:
auto v = std::vector<int>({1,2,3});
auto s = std::set<double>({0.5,1.5});
auto range = combineElements(v.begin(),v.end(),s.begin(),s.end(),[](int i,double d){ return std::pair{i,d}; });
for (auto [i,d] : range)
std::cout << std::to_string(i) << ',' <<std::to_string(d) << ";";
// Expected output: 1,0.5;1,1.5;2,0.5;2,1.5;3,0.5;3,1.5;
我检查了 boost::iterators 的文档并发现:
- Zip:这将第一个范围的第 n 个元素与第二个范围的第 n 个元素组合在一起。但是,不会将第 n 个元素与第 m 个元素组合在一起。
- 生成器:需要提供的生成器可以手动记账 6 个迭代器:两个范围的开始、结束和当前。但是,它没有办法阻止它。
- 函数输入:与生成器类似,我们可以将这些迭代器置于状态中,并使用结束迭代器为结束迭代器创建结束状态。但是,状态并未提供给生成器来计算迭代器的值。
- 排列:适用于单个范围
- 转换:适用于单一范围
我认为在这种情况下唯一的选择是手工编写客户迭代器是否正确?
解决方法
我认为在这种情况下唯一的选择是手工编写客户迭代器是否正确?
几乎是的。您可能希望将其分解为一个迭代器适配器,该适配器对每个元素重复 N 次,以及一个重复整个范围 M 次的迭代器适配器,这将允许您zip
一对。
template <class Iterator>
class repeat_iterator
: public boost::iterator::iterator_adaptor< repeat_iterator<Iterator>,Iterator >
{
typedef boost::iterator::iterator_adaptor< repeat_iterator<Iterator>,Iterator > super_t;
friend class boost::iterator::iterator_core_access;
size_t len = 1;
size_t curr = 0;
public:
repeat_iterator() {}
explicit repeat_iterator(Iterator x,size_t len,curr = 0)
: super_t(x),len(len),curr(curr) {}
private:
void increment() {
if (++curr == len) {
curr = 0;
++base_reference();
}
}
void decrement() {
if (curr-- == 0) {
curr = len - 1;
--base_reference();
}
}
void advance(typename super_t::difference_type n)
{
n += curr;
base_reference() += n / len;
curr = n % len;
}
template <class OtherIterator>
typename super_t::difference_type
distance_to(unstride_iterator<OtherIterator> const& y) const
{
return ((base() - y.base()) * len) + (curr - y.curr);
}
};
template <class Iterator>
class cycle_iterator
: public boost::iterator::iterator_adaptor< cycle_iterator<Iterator>,Iterator >
{
typedef boost::iterator::iterator_adaptor< cycle_iterator<Iterator>,Iterator > super_t;
friend class boost::iterator::iterator_core_access;
Iterator first;
Iterator last;
public:
cycle_iterator() {}
explicit cycle_iterator(Iterator first,Iterator last)
: super_t(first),first(first),last(last) {}
private:
void increment() {
if (++base_reference() == last) {
base_reference() = first;
}
}
void decrement() {
if (base_reference() == first) {
base_reference() = last - 1;
}
}
void advance(typename super_t::difference_type n)
{
n += std::distance(first,base_reference());
n %= std::distance(first,last);
base_reference() = first + n;
}
};
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。