获取向量中唯一元素的索引

时间:2021-04-20 05:34:20

标签: c++

C++ 中是否有任何 STL/Boost 函数可以让我找到向量中所有唯一元素的索引?

我见过很多解决方案来寻找独特的元素,但我需要它们的索引。

  vector<int> v = { 1,1,1, 2,2,2,2, 3, 3, ,4,5,5,5,5,5,5 };// already sorted

或者我需要唯一元素的第一个索引

vector<int> unique_index={0,3,7,9,10};

或者我需要唯一元素的最后一个索引

vector<int> unique_index={2,6,8,9,15};

2 个答案:

答案 0 :(得分:4)

一个简单的方法(除了跟踪最后一个元素是什么)是使用 std::set 来测试当前元素在向量的元素中是否是唯一的——到目前为止看到的,并填充使用时您的唯一索引。这提供了一次通过以收集看到第一个唯一元素的索引,例如

#include <iostream>
#include <vector>
#include <set>

int main (void) {
    
    std::vector<int> v = { 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5 },
                uniqueidx{};
    std::set<int> s{};
    
    for (size_t i = 0; i < v.size(); i++)
        if (s.insert(v[i]).second)
            uniqueidx.push_back(i);
    
    for (const auto i : uniqueidx) 
        std::cout << i << '\n';
}

示例使用/输出

$ ./bin/set_index_of_unique_in_vector
0
3
7
10
11

注意:最后两个值是 1011,而不是 910 - 您在您的向量初始化,例如 3, ,4)

如果你只是想要一个简单的旧循环来做同样的事情,你可以使用:

#include <iostream>
#include <vector>

int main (void) {
    
    std::vector<int> v = { 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5 },
                uniqueidx{};
    
    for (size_t i = 0; i < v.size(); i++)
        if (!i || v[i-1] != v[i])
            uniqueidx.push_back(i);
    
    for (const auto i : uniqueidx) 
        std::cout << i << '\n';
}

(相同的输出)

使用 std::set 的方法的好处是您将唯一性的确定留给 std::set,使用简单的循环——这取决于您....

检查一下,如果您有问题,请告诉我。

答案 1 :(得分:1)

类似于 David 对使用 std::set 的回答,您也可以将 std::map 与其成员函数 try_emplace(key, value) 一起使用:

#include <iostream>
#include <vector>
#include <map>

int main (void) {
    
    std::vector<int> v = { 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 5, 5, 5, 5, 5, 5 };
    std::map<int, int> m;
    
    for (size_t i = 0; i < v.size(); i++)
    {
        // `i` is only entered if the `m[v[i]]` isn't filled yet.
        m.try_emplace(v[i], i);
    }

    for (auto [valueFromV, indexFromV] : m) 
    {
        std::cout << indexFromV << '\n';
    }
}
相关问题