我在理解如何使用std::find()
函数的反向迭代器方面遇到了一些麻烦。我相信如果我能看到一个完成以下任务的例子,我就能完全理解它。
所以,假设我想要搜索std::vector
;但是,我不想搜索典型的方式。我想找到第一次出现的值从某个索引开始并朝向向量的开头。举例说明:
3 | 4 | 7| 4| 2| 6| 3| ^ ^ |<------------| start_point
搜索:在给定上述搜索布局的情况下,找到第一个出现的4
预期结果:指数3
我很确定在这种情况下必须使用反向迭代器,但我无法弄清楚如何去做。
答案 0 :(得分:5)
首先设置起始位置:
auto it = v.rbegin() + 2; // two from the end
然后搜索:
auto kt = std::find(it, v.rend(), 4);
如果kt == v.rend()
,则找不到任何元素;否则我们可以通过简单的距离计算从前面计算索引:
if (kt == v.rend()) {
std::cerr << "Element 4 not found.\n";
std::abort();
} else {
auto n = std::distance(kt, v.rend()) - 1;
std::cout << "Element 4 found at position v[" << n << "].\n";
}
答案 1 :(得分:4)
如果您正在使用std::vector
或任何其他提供随机访问迭代器的容器,您可以使用算术推进迭代器,就像使用指针一样。你的示例向量有7个元素,你想从索引5开始,所以你可以得到一个正常的迭代器到那个元素:
auto i = v.begin() + 5;
对于反向迭代器,你从向量的后面开始,而不是从前面开始,所以为了获得正确的偏移,你必须从大小中减去所需的索引,如下所示:
auto i = v.rbegin() + (v.size() - 5);
在你的例子中,这将是2
,所以反向迭代器将开始指向最后一个元素,然后向开头移动两个空格,到达你想要的起点。
然后,您可以按正常方式使用std::find
:
auto found = std::find(v.rbegin() + (v.size() - 5), v.rend(), 4);
if(found == v.rend()) {
std::cout << "No element found." << std::endl;
} else {
std::cout << "Index " << (v.rend() - found) << std::endl;
}
请记住,在测试std::find
的结果以查看是否找到任何内容时,您需要使用rend()
,而不是end()
。当您将反向迭代器与普通迭代器进行比较时,您需要比较实际位置,而不是开始时的偏移量,因此v.rend() != v.end()
。
如果您没有随机访问迭代器(例如,在std::list
中),则无法使用指针式算术,因此您可以使用std::advance
来提升迭代器到特定位置,std::distance
来获取两个迭代器之间的距离。
答案 2 :(得分:2)
尝试类似以下内容
#include <iostream>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::vector<int> v = { 3, 4, 7, 4, 2, 6, 3 };
std::vector<int>::size_type pos = 4;
auto it = std::find(std::next(v.rbegin(), v.size() - pos), v.rend(), 4);
if (it != v.rend())
{
std::cout << std::distance(v.begin(), it.base() - 1) << std::endl;
}
}