Nic*_*den 5 c++ stl stl-algorithm
根据这篇文章,一种可能的实现std::unique是
template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last)
{
if (first == last)
return last;
ForwardIt result = first;
while (++first != last) {
if (!(*result == *first) && ++result != first) {
*result = std::move(*first);
}
}
return ++result;
}
Run Code Online (Sandbox Code Playgroud)
但是,我不明白迭代器比较的用途是什么?为什么if (!(*result == *first) && ++result != first)而不只是if (!(*result++ == *first))?比较两个迭代器的目的是什么?
让我们将代码重写为更小的步骤(代码相当于问题中的代码 - 我刚刚将 if 语句拆分为两个单独的部分):
template<class ForwardIt>
ForwardIt unique(ForwardIt first, ForwardIt last)
{
// are there elements to test?
if (first == last)
return last;
// there are elements so point result to the first one
ForwardIt result = first;
// then increment first and check if we are done
while (++first != last) {
// if the value of first is still the same as the value of result
// then restart the loop (incrementing first and checking if we are done)
// Notice that result isn't moved until the values differ
if (*result == *first)
continue;
// increment result and move the value of first to this new spot
// as long as they don't point to the same place
// So result is only moved when first points to a new (different) value
if (++result != first) {
*result = std::move(*first);
}
}
// return one past the end of the new (possibly shorter) range.
return ++result;
}
Run Code Online (Sandbox Code Playgroud)
下面是一个例子:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 2 | 3 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
步骤 1 - 先递增并将 first 的值与结果的值进行比较:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 2 | 3 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 2 步 - 值不同,所以增加结果,但现在它们指向同一个地方,所以移动是多余的,我们不这样做
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 2 | 3 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 3 步 - 先递增并将 first 的值与结果的值进行比较:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 2 | 3 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 4 步 - 值相同,因此重新启动循环(首先递增并将 first 的值与结果的值进行比较):
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 2 | 3 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 5 步 - 值不同,因此增加结果,它们指向不同的位置,因此将 first 的值移动到 result 的值中:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 3 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 6 步 - 先递增并将 first 的值与结果的值进行比较:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 3 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 7 步 - 值不同,因此增加结果,它们指向不同的位置,因此将 first 的值移动到 result 的值中:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 8 步 - 先递增并将 first 的值与结果的值进行比较:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 9 步 - 值相同,因此重新启动循环(首先递增并将 first 的值与结果的值进行比较):
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 10 步 - 值相同,因此重新启动循环(首先递增并将 first 的值与结果的值进行比较):
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 | 4 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 11 步 - 值不同,因此增加结果,它们指向不同的地方,因此将 first 的值移动到 result 的值中:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 | 5 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^ ^
first last
Run Code Online (Sandbox Code Playgroud)
第 12 步 - 首先递增,while 循环结束,因为 first 和 last 指向同一个位置 - 然后在循环递增结果之后,它成为唯一范围的新结束迭代器:
result
v
+-----+-----+-----+-----+-----+-----+-----+-----+
| 1 | 2 | 3 | 4 | 5 | 4 | 4 | 5 |
+-----+-----+-----+-----+-----+-----+-----+-----+
^
last&first
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
518 次 |
| 最近记录: |