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};
答案 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
(注意:最后两个值是 10
和 11
,而不是 9
和 10
- 您在您的向量初始化,例如 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';
}
}