查找向量中所有元素出现的索引

时间:2014-09-15 10:44:11

标签: c++ vector

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

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);

4 个答案:

答案 0 :(得分:13)

再次调用std::find_if,先前返回的迭代器(加一)作为开头。在std::find_if返回A.end()之前循环执行。


示例代码

std::vector<int>::iterator iter = A.begin();
while ((iter = std::find_if(iter, A.end(), 0)) != A.end())
{
    // Do something with iter

    iter++;
}

答案 1 :(得分:1)

使用lamda回答@ some-programmer-dude:

#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++;
}

答案 2 :(得分:0)

尝试一下: char c:要获取其索引的元素。 我使用了一个字符串,但是这个相同的代码可以很好地与向量一起工作。 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;
}

答案 3 :(得分:0)

如果您考虑 #includes 和 usings,这个解决方案会有点长,但这在更大的代码库中是无关紧要的。

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

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

定义 second_is_zero 有点矫枉过正;如果您习惯了 auto constexpr equal_to = std::equal_to<>{};compose 等函数式实用程序,则改为定义 partial 会导致以下结果仍然可读:

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;
}