【发布时间】:2020-08-30 16:41:30
【问题描述】:
假设我有一个带有数字的向量:10 10 58 31 63 40 76。我想找到最小元素最后一次出现的位置。最小元素是10。 10 最后出现的位置是1。
我尝试过使用反向迭代器,但我还是有点困惑。
【问题讨论】:
标签: c++
假设我有一个带有数字的向量:10 10 58 31 63 40 76。我想找到最小元素最后一次出现的位置。最小元素是10。 10 最后出现的位置是1。
我尝试过使用反向迭代器,但我还是有点困惑。
【问题讨论】:
标签: c++
假设向量:
std::vector<int> v = { 10, 10, 58, 31, 63, 40, 76 };
您可以使用反向迭代器和std::min_element 获取最后一个最小元素:
auto last_min = std::min_element(std::rbegin(v), std::rend(v));
然后使用std::distance 和"base" of the reverse iterator 获取到向量开头的距离:
auto last_min_distance = std::distance(std::begin(v), last_min.base());
最后减一得到索引:
auto last_min_index = last_min_distance - 1;
【讨论】:
您使用反向迭代器的想法是正确的做法。
首先,您需要找到最后一个元素。
这可以通过std::min_element 和反向迭代器来完成:
auto min_elem_iter = std::min_element(std::crbegin(vec), std::crend(vec));
其中vec 是您要搜索的std::vector。
现在您有了一个指向您搜索的最后一个元素的迭代器。您需要检查它是否与std::crend(vec) 相同,以确保它指向一个有效的元素。
如果要知道索引,需要std::distance,可以用来计算两个迭代器之间的距离。有了它,您可以找出std::crbegin(vec) 和指向我们找到的元素的迭代器之间的距离。
这可以与向量的大小一起使用来计算索引。
总之,你可以得到你想要的:
template<class T>
auto getIndexOfLastMin(const std::vector<T>& vec)
-> std::optional<std::size_t>
{
auto last_elem_iter = std::min_element(std::crbegin(vec),
std::crend(vec));
if(last_elem_iter == std::crend(vec)){
return std::nullopt;
}
auto idx = std::distance(std::rbegin(vec), last_elem_iter);
return static_cast<std::size_t>(vec.size() -1 - idx);
}
您可以结帐并运行代码here
【讨论】:
假设最小元素是 k
for (int i = 0; i < vector.size(); i++)
{
if( k == vector[i])
{
index = i;
}
}
在循环结束时,索引将是向量中最小元素的最后位置。
【讨论】:
...如果您还没有预先找到最小元素,您可以这样做:
int min_element = std::numeric_limits <int>::max;
size_t index = 0;
for (size_t i = 0; i < vector.size(); i++)
{
if (vector[i] <= min_element)
{
min_element = vector[i];
index = i;
}
}
【讨论】:
并非一切都必须复杂(这是现代 C++ 的主要缺陷:任何程序员都想成为天才)。保持简单:
#include <vector>
#include <limits.h>
int main()
{
std::vector<int> v = { 10, 10, 58, 31, 63, 40, 76 }; // This is the vector
int min = INT_MAX;
size_t i = 0, last_min_i = 0;
for (auto item : v) {
if (item <= min) {
min = item;
last_min_i = i;
}
i++;
}
// last_min_i holds the result
}
【讨论】:
我假设您已经找到了最小元素。然后一个简单的向后循环似乎最简单
size_t index = vec.size();
do
{
--index;
}
while (vec.at(index) != min_element);
如果碰巧你犯了一个错误,那么使用at 将导致异常,这比使用[] 得到的UB 更安全。
你可以用反向迭代器做一些事情,但为什么会复杂呢?
【讨论】: