c++ - 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 个迭代器:两个范围的开始、结束和当前。但是,它没有办法阻止它。
- 函数输入:与 Generator 类似,我们可以将这些迭代器置于状态中,并使用 end-iterators 为 end-iterator 创建一个结束状态。但是,状态并没有提供给生成器来计算迭代器的值。
- 排列:适用于单个范围
- 变换:在单个范围内工作
我是否正确得出结论,在这种情况下,唯一的选择是手动编写客户迭代器?
解决方案
我是否正确得出结论,在这种情况下,唯一的选择是手动编写客户迭代器?
几乎是的。您可能希望将其分解为一个迭代器适配器,该适配器将每个元素重复 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;
}
};
推荐阅读
- python - pynput模块右键不工作?
- c - While 中哪个条件成立?
- powerbi - Power BI DAX - 如果包含来自引用表的字符串,则计算记录数
- java - 如何打印二维字符数组(JAVA)
- python - 是否可以在 Linux 中跟踪用户空闲时间(鼠标/键盘输入)(没有外部库或程序)
- python - 我正在使用 pyautogui 来检测鼠标位置。我有一个 tkinter 窗口,但是 pyautogui 仅在我关闭 tkinter 窗口时才有效
- git - Plesk 在 git 存储库更改时自动更新子模块
- rust - 为什么匹配 Regex::find 的结果会抱怨期望 struct regex::Match 但找到元组?
- ssis - Azure Devops 构建 SSIS 任务
- java - 嵌套 for 循环在两个字符串之间进行迭代