如何复制只有两个迭代器的数据?
Posted
技术标签:
【中文标题】如何复制只有两个迭代器的数据?【英文标题】:How to copy data having only two iterators? 【发布时间】:2019-10-20 09:51:32 【问题描述】:我正在创建一个合并排序算法,该算法的步骤之一涉及创建子数组,这些子数组是执行排序的序列的一部分。作为输入,我在容器的开头和结尾获取迭代器,然后在开头和结尾之间找到一个中间迭代器,然后就需要根据接收到的迭代器复制数据。
template<class Iterator>
void merge_sort(Iterator t_begin, Iterator t_end)
// Recursion ends when the sequence becomes 1
if(std::distance(t_begin, t_end) < 2)
return;
// Combining two sorted sequences
auto merge = [](Iterator begin, Iterator middle, Iterator end)
// Supposed, subarrays are sorted
const std::deque<std::remove_reference_t<decltype(*begin)>> left begin, middle, right middle, end;
auto left_it = left.begin(), right_it = right.begin();
// Merge two subarrays into one sorted
for(Iterator itr = begin; itr != end; ++itr)
if(left_it == left.end())
*itr = *right_it++;
else if(right_it == right.end())
*itr = *left_it++;
else if(*left_it <= *right_it)
*itr = *left_it++;
else
*itr = *right_it++;
;
Iterator middle = t_begin + static_cast<std::size_t>((std::distance(t_begin, t_end) / 2));
merge_sort(t_begin, middle);
merge_sort(middle, t_end);
merge(t_begin, middle, t_end);
作为一种解决方案,我使用队列数据结构的显式声明。
const std::deque<std::remove_reference_t<decltype(*begin)>> left begin, middle, right middle, end;
如何让两个迭代器将数据复制到另一个变量而不绑定到特定容器,并使用例如这些迭代器所属的那个?有没有更优雅的方法来做到这一点?
【问题讨论】:
不,可能没有更优雅的方式。如果要复制数据,则必须使用容器。您可以通过容器或分配器将选择留给用户。 不相关,但使用vector
s 代替deque
s 会更有效。
【参考方案1】:
您正在寻找的不仅仅是 C++ 的东西,而是算法的东西。以默认(也是最快)方式实现的合并排序需要额外的临时内存。
有一些方法可以避免这种情况,称为就地合并排序或简称为就地合并。虽然它非常重要,但搜索一下,你会发现多种算法可以做到这一点。
【讨论】:
是的,我知道在 STL 中有一个函数 (std::merge) 结合了两个排序范围,它比我编写的 lambda 函数更能解决我的问题。但问题的目标恰恰是如何拥有两个迭代器来获取数据的副本而不绑定到特定的容器。所以如果以后出现类似的情况,我就知道如何正确解决了。感谢建议的方法,我一定会研究这些点。 @DmitryEmelyanov 我根本不是在谈论std::merge
。无论如何,在 C++ 中你负责内存管理,在 C++ 中没有“存储这个但我不在乎什么容器”的构造。在这些情况下,std::vector
应该是您的默认选择,它是用于存储简单元素序列的最简单容器。以上是关于如何复制只有两个迭代器的数据?的主要内容,如果未能解决你的问题,请参考以下文章
STL中的vector和list的迭代器引申的关于迭代器的总结