我做了一些事情来实现两个范围的交织。这是问题所在。
说我有两个范围[a1, b1), call R1
和[a2, b2) call R2
。现在,假设他们的std::distance
结果相同,例如n
。我想写一个算法
std::interleave(a1, b1, a2, b2, bool swap)
这将对元素进行重新排序,使得R2的一个元素将通过所有2n
元素跟随在R1的元素之后。根据{{1}}的值,还应该重新排序,因为R1的一个元素后跟R2的一个元素。
我使用了一个额外的存储和两个for循环来做到这一点。这个解决方案很简单。如果再尝试一点,我也可以提出就地解决方案。但是我想要的是,我想通过从STL组装算法来实现这一目标。您如何使用STL解决此问题?如果就地解决方案会更好,但是只要我们使用STL中的算法,我也愿意使用其他存储。
编辑:在给定范围内的元素排列不应更改。换句话说,实际上应该类似于swap
。这就是为什么我无法提出使用stable_interleave
的东西的原因。
应用:一种应用是将视频和图像格式从平面转换为非平面或半平面。
答案 0 :(得分:1)
我使用std::merge
的建议可能会失败。我没有足够的创造力去看为什么有人会写merge
来写,但是却违反了下面评论中指出的Compare的要求,所以有人可以写。
无论如何,merge
是一个过大的解决方案。由于merge
的预期用途比我们在这里要完成的工作更为复杂,因此隐藏额外工作量的代码行更少。
示例:
#include <iostream>
#include <iterator>
#include <algorithm>
#include <vector>
#include <list>
#include <deque>
template<typename IN1,
typename IN2,
typename OUT>
inline OUT interleave(IN1 it1,
IN1 end1,
IN2 it2,
IN2 end2,
OUT out)
{
// interleave until at least one container is done
while (it1 != end1 && it2 != end2)
{
// insert from container 1
*out = *it1;
out++;
it1++;
// insert from container 2
*out = *it2;
out++;
it2++;
}
if (it1 != end1) // check and finish container 1
{
return std::copy (it1, end1, out);
}
else if (it2 != end2)// check and finish container 2
{
return std::copy (it2, end2, out);
}
return out; // both done
}
int main()
{
// fill the containers with numbers
std::vector<int> in1 = {1,3,5,7,9};
std::list<int> in2 = {8,6,4,2};
// construct output container of sufficient size.
// Could also use empty container and *_inserter
std::deque<int> out(in1.size() + in2.size());
// Container-agnostic. reads from vector and list and stores in deque
interleave(in1.begin(), in1.end(),
in2.begin(), in2.end(),
out.begin());
for (int val: out)
{
std::cout << val << ' ';
}
}
注意:调用者应该在输入参数的顺序颠倒的情况下进行调用,而不是使用交换输入顺序的选项并使所有interleave
的用户为此付费。