也许他们想要帮助我们,考虑到数组从0开始。所以我们可能会认为如果我们想要对前n个元素进行排序,我们会一直到v [n],但实际上我们只去v [N-1]。所以这可以解释这个函数排序到最后的事实 - 1.但在这种情况下,为什么不首先开始 - 1?在乞讨时我们放1并且我们从v [1]开始但是然后我们放n并且停在v [n-1]。为什么?如果它确实从一个考虑数组,它应该包括最后一个元素。这些只是我 - 可能是愚蠢的 - 想法?这就是为什么我会欣赏一个真正的解释。谢谢!
编辑:非常感谢你的回答。我可以看到有很多优点,在这个范围内一切看起来都很正常。我会尽力记住你的所有例子,以便在我的脑海中清楚地表达出来。
答案 0 :(得分:4)
这是为了与标准C ++库的所有容器中的迭代器语义保持一致:begin()
始终是包容性的,而end()
始终是独占的,因为它"指向"到容器结束后的位置。
这与指向数组元素的指针的行为一致:
int data[SIZE];
int *begin = data; // Inclusive
int *end = &data[SIZE]; // Exclusive
答案 1 :(得分:1)
通过这种方式定义范围可以轻松处理子范围。这是一个愚蠢的例子:
void apply(int* begin, int* end, void (*f)(int)) {
if (begin == end)
; // nothing to do
else if (begin + 1 == end)
f(*begin);
else {
int* mid = begin + (end - begin) / 2;
apply(begin, mid, f);
apply(mid, end, f);
}
}
这里有两点重要。首先,检测空范围很简单:begin == end
。其次,分成两个范围同样简单。只需生成一个中间点mid
并将其用作每个范围的结尾:[begin, mid)
和[mid, end)
是两个范围,涵盖第一个范围内的所有元素。
现在尝试编写执行相同操作但使用双重包含或双重独占范围的代码。对比和比较。
答案 2 :(得分:1)
为什么C ++排序范围[first,last]?
对于所有迭代器范围都是如此,所以我想你一直在问为什么迭代器范围一般表示为[first, last)
。
回答(或更确切地说,回答)这个问题:为什么不呢?你认为有更好的选择吗?那是什么选择?
假设您希望将范围表示为[first, last]
。这就是迭代器需要处理的方式:
表示长度为1的范围。让it
为迭代器:
representation - how to treat
[first, last) - it, it + 1
[first, last] - it, it
[first, last]
对单值具有更紧凑的表示。我明白为什么这看起来不错。但是+ 1
与范围的长度有明确的联系,这也很好。
代表长度范围n
:
[first, last) - begin, begin + n
[first, last] - begin, begin + n - 1
这里与长度的连接显示了它的伟大。 [first, last)
更简单。
代表空范围:
[first, last) - it, it
[first, last] - it + 1, it
这确实是个大问题。 [first, last]
需要两个不同的迭代器值来表示空范围。例如,考虑一个向量。您需要在第一个值之前使用迭代器,并在最后一个值之后使用迭代器来表示它(因为没有要指向的值)。