C++ 如何使用end()迭代器扩展范围
不确定这是正确的任务 我正在用stl风格编写一个与经典排序相关的算法。 原型是:C++ 如何使用end()迭代器扩展范围,c++,stl,iterator,stl-algorithm,C++,Stl,Iterator,Stl Algorithm,不确定这是正确的任务 我正在用stl风格编写一个与经典排序相关的算法。 原型是: template<typename RAIter> void Algo(RAIter first, RAIter last) { .... size_t size = std::distance(first, last); RAIter midIter =first; std::advance(midIter, size / 2 - 1); Algo(fir
template<typename RAIter>
void Algo(RAIter first, RAIter last) {
....
size_t size = std::distance(first, last);
RAIter midIter =first;
std::advance(midIter, size / 2 - 1);
Algo(first, midIter);
Algo(midIter + 1, last);
....
}
但这对我来说并不正确因为,
最初,它的范围如下所示:
向量v;
开始,结束;
但是,在内部,在递归调用中,子范围不包含end元素
这种情况下的典型技术是什么 我建议两种选择 首选使算法在内部不需要包含last。在您的情况下,可以这样做:
template<typename RAIter>
void Algo(RAIter first, RAIter last) {
....
size_t size = std::distance(first, last);
if (size <= 1) {
// special processing of single-item or empty range
return;
}
RAIter midIter =first;
std::advance(midIter, size / 2);
Algo(first, midIter); // midIter not included
Algo(midIter, last); // it's included here instead
}
你的算法不一致。你调用它时端被排除,但你递归调用它时端被包括和排除。实际上问题是-如何为内部调用添加端元素如果内部调用与用户调用的契约不同,您需要一个不同的函数。问题:为什么递归调用需要end元素?我想不出任何需要这些信息的经典排序算法。传递结束元素是stl中的一种常见做法,在stl中,所有算法都使用范围[首先,lastE.g.容器有6个元素。使用end作为初始调用时,distance返回6,但在下一步中,它返回2而不是预期的3,这很清楚,因为初始调用包含7个带end的元素,但下一次调用只得到3个元素,没有end。@amigo421注意std::advancemediter,size/2;而不是size/2-1。顺便说一句,size/2-1是wr在这两种情况下,我只是没有编辑第二种方法。@amigo421但您可能不习惯将范围分成相等的部分,谁知道这是一个学习内部排序合并排序的示例,您的第二种方法对我来说看起来不错,但是,当然,我更喜欢在单个函数中实现这种方法
template<typename RAIter>
void AlgoImpl(RAIter first, RAIter last) {
....
// looks like this is more correct:
// size_t size = std::distance(first, last) + 1;
size_t size = std::distance(first, last);
RAIter midIter =first;
std::advance(midIter, size / 2 - 1); // and here "- 1" seems wrong
AlgoImpl(first, midIter);
AlgoImpl(midIter + 1, last);
....
}
template<typename RAIter>
void Algo(RAIter first, RAIter last) {
if (first == last) {
return;
}
AlgoImpl(first, last - 1);
}