我有一个由一些值组成的向量以及一个由 0 和 1 组成的掩码向量。例如:
std::vector<int> mask{0, 0, 1, 0, 1, 1, 0};
std::vector<double> vec{7.1, 1.0, 3.2, 2.0, 1.8, 5.0, 0.0};
Run Code Online (Sandbox Code Playgroud)
我需要在其中找到最小元素(其索引)vec,但仅在其中mask为 1。在本例中,索引 4 处为 1.8。
这是我使用循环的解决方案
double minVal = std::numeric_limits<double>::max();
int minIndex;
for (size_t i = 0; i < vec.size(); ++i)
{
if (vec[i] < minVal && mask[i] == 1)
{
minVal = vec[i];
minIndex = i;
}
}
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有一种方法可以通过使用标准库(例如std::min_element和 lambda)来做到这一点,最好不使用 for 循环?
您可以转换为组合vector,使用 max double 作为掩码值的替换,并将其与std::min_element
#include <algorithm>
#include <iostream>
#include <limits>
#include <vector>
int main()
{
std::vector<bool> mask{0, 0, 1, 0, 1, 1, 0};
std::vector<double> vec{7.1, 1.0, 3.2, 2.0, 1.8, 5.0, 0.0};
std::vector<double> combined;
std::transform(vec.begin(), vec.end(), mask.begin(),
std::back_inserter(combined),
[](double v, bool mask) {
return mask ? v : std::numeric_limits<double>::max(); });
auto it = std::min_element(combined.begin(), combined.end());
std::cout << "min=" << *it << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
有关实例,请参阅https://ideone.com/FncV2r 。
获取索引相当容易使用std::distance
std::cout << "index=" << std::distance(combined.begin(), it) << "\n";
Run Code Online (Sandbox Code Playgroud)
并将其应用于原始向量将是
auto index = std::distance(combined.begin(), it);
auto it_vec = vec.begin() + index;
Run Code Online (Sandbox Code Playgroud)
请记住,即使此解决方案使用 std 算法和 lambda,提问者的简单 for 循环效率更高。
这是因为 for 循环不需要额外的空间(组合向量),并且在一次运行中完成,而transform和min_element需要两次循环才能产生相同的结果。
因此,有时会出现“老式”循环。