查找向量中某个元素的所有引用的索引

Finding the indexes of all occurrences of an element in a vector

本文关键字:引用 索引 元素 向量 查找      更新时间:2023-10-16

假设我有一个向量A = {1 0 1 1 0 0 0 1 0}。现在,我想获得作为另一个向量B返回的0的所有出现的索引。

template< class InputIt, class T>
std::vector<int> IndicesOf(InputIt first, InputIt last, const T& value) {
}

这是一个开始:

std::vector<int>::iterator iter = std::find_if(A.begin(), A.end(), 0);
B = std::distance(A.begin(), iter);

只需再次调用std::find_if,以之前返回的迭代器(加一)为开头。循环执行,直到std::find_if返回A.end()


样本代码

#include <algorithm> //find_if
bool isZero(int x){
    return x == 0;
}
std::vector<int>::iterator iter = A.begin();
while ((iter = std::find_if(iter, A.end(), isZero)) != A.end())
{
    // Do something with iter
    iter++;
}

对于@some programmer dude with lamda的答案:

#include <algorithm> //find_if
std::vector<int> A{1, 0, 1, 1, 0, 0, 0, 1, 0};
std::vector<int> B;
std::vector<int>::iterator it = A.begin();
while ((it = std::find_if(it, A.end(), [](int x){return x == 0; })) != A.end())
{
    B.push_back(std::distance(A.begin(), it));
    it++;
}

试试这个:charc:要获取其索引的元素。我使用了一个字符串,但同样的代码可以很好地处理向量。vecky存储找到的所有索引。

std::vector<int> getIndex(string s, char c)
{
    std::vector<int> vecky;
    for (int i = 0; i != s.length(); i++)
    {
        if (s[i] == c)
        {
            vecky.push_back(i);
        }
    }
    return vecky;
}

如果考虑#include s和using s,这个解决方案会更长一些,但在更大的代码库中这是无关紧要的。

如果没有这些,并且考虑到可以在头中存储一些有用的函数对象,如firstsecond,核心部分就变成了一行:

auto result = enumerate(v) | filter(second_is_zero) | transform(first);

定义second_is_zero有点过头了;相反,定义auto constexpr equal_to = std::equal_to<>{};会导致以下内容,一旦您习惯了composepartial等功能实用程序,这些内容仍然可读:

auto result = enumerate(v) | filter(compose(partial(equal_to, 0), second))
                           | transform(first);

这是完整的代码,尽管

#include <boost/hana/functional/compose.hpp>
#include <boost/hana/functional/partial.hpp>
#include <functional>
#include <iostream>
#include <vector>
#include <range/v3/view/enumerate.hpp>
#include <range/v3/view/filter.hpp>
#include <range/v3/view/transform.hpp>
using boost::hana::compose;
using boost::hana::partial;
using namespace ranges::views;
int main()
{
  std::vector<int> v{1,0,1,1,0,0,0,1,0};
  // define some useful function object
  auto constexpr first = [](auto const& pair){ return pair.first; };
  auto constexpr second = [](auto const& pair){ return pair.second; };
  auto constexpr second_is_zero = compose(partial(std::equal_to<>{},0), second);
  // oneline to get the result (it's in a view, not a vector)
  auto result = enumerate(v)           // attach indexes 0,1,2,... to the elements
              | filter(second_is_zero) // filter based on second
              | transform(first);      // extract the indexes
  // the following prints 14568
  for (auto i : result) {
    std::cout << i;
  }
  std::cout << std::endl;
}