一个可能看起来微不足道的问题,但我想知道在将包含重复整数的数组转换为
unordered_set
后,是否有一种方法可以获得唯一的整数计数。为了清楚起见,我从一些数组开始,将其变成一个 unordered_set
,突然间,unordered_set
只包含唯一的整数,而我只是在 unordered_set
中整数的重复数之后。unordered_set.count(index)
)
一个可能看起来微不足道的问题,但我想知道在将包含重复整数的数组转换为 unordered_set 后,是否有一种方法可以获得唯一的整数计数。
如果容器是连续的,例如数组,那么我相信您可以在进行一些迭代器数学运算后使用
ptrdiff_t
来对它们进行计数。不过,我不确定不连续的容器。
既然你从数组开始:
unique
unique
返回iter.end()
ptrdiff_t count
和 iter.begin()
计算
iter.end()
请记住,步骤 3 中的计算需要针对
sizeof
和元素进行调整。
但套用 Beta 的话,有些容器适合这样做,而另一些容器则不适合。如果您有一个无序的集合(或地图或树),那么信息将不容易获得。
根据你对user2357112问题的回答我会写一个解决方案。 因此,我们假设我们将使用一个向量而不是 unordered_set,并且我们的向量具有如下值:
{1, 1, 1, 3, 4, 1, 1, 4, 4, 5, 5};
所以,我们想要获取特定值在向量中出现的次数(我认为是在不同的向量中),对吧?在这种特定情况下,结果将是:1 出现 5 次,3 出现 1 次,4 出现 3 次,5 出现 2 次。
要完成此任务,一种可能的解决方案如下:
第1点的代码可以是这样的:
template <typename Type>
vector<Type> unique_entries (vector<Type> vec) {
for (auto iter = vec.begin (); iter != vec.end (); ++iter) {
auto f = find_if (iter+1, vec.end (), [&] (const Type& val) {
return *iter == val;
});
if (f != vec.end ()) {
vec.erase (remove (iter+1, vec.end (), *iter), vec.end ());
}
}
return vec;
}
第2点的代码可以是这样的:
template <typename Type>
struct Properties {
Type key;
long int count;
};
template <typename Type>
vector<Properties<Type>> get_properties (const vector<Type>& vec) {
vector<Properties<Type>> ret {};
auto unique_vec = unique_entries (vec);
for (const auto& uv : unique_vec) {
auto c = count (vec.begin (), vec.end (), uv); // (X)
ret.push_back ({uv, c});
}
return ret;
}
当然,我们不需要 Properties 类来存储键和计数值,您可以仅返回一个 int 向量(带有元素计数),但正如我所说,这是可能的解决方案之一。因此,通过使用 unique_entries 我们得到一个具有唯一条目的向量 (:) ),然后我们可以迭代整个向量 vec (get_properties,使用 std::count 标记为 (X)),并使用 push_back 属性反对向量ret。
第3点的代码可以是这样的:
template <typename Type>
void show (const vector<Properties<Type>>& vec) {
for (const auto& v : vec) {
cout << v.key << " " << v.count << endl;
}
}
// usage below
vector<int> vec {1, 1, 1, 3, 4, 1, 1, 4, 4, 5, 5};
auto properties = get_properties (vec);
show (properties);
结果如下所示:
1 5
3 1
4 3
5 2
值得注意的是,这个示例是使用模板编写的,以提供选择向量中元素类型的灵活性。如果你想存储long、long long、short等值,而不是int类型,你所要做的就是改变源向量的定义,例如:
vector<unsigned long long> vec2 {1, 3, 2, 3, 4, 4, 4, 4, 3, 3, 2, 3, 1, 7, 2, 2, 2, 1, 6, 5};
show (get_properties (vec2));
将产生:
1 3
3 5
2 5
4 4
7 1
6 1
5 1
这是想要的结果。
还有一点要注意,您也可以使用字符串向量来完成此操作。
vector<string> vec_str {"Thomas", "Rick", "Martin", "Martin", "Carol", "Thomas", "Martin", "Josh", "Jacob", "Jacob", "Rick"};
show (get_properties (vec_str));
结果是:
Thomas 2
Rick 2
Martin 3
Carol 1
Josh 1
Jacob 2
我假设您正在尝试获取唯一值及其出现次数的列表。如果是这样的话,那么
std::map
提供了最干净、最简单的解决方案:
//Always prefer std::vector (or at least std::array) over raw arrays if you can
std::vector<int> myInts {2,2,7,8,3,7,2,3,46,7,2,1};
std::map<int, unsigned> uniqueValues;
//Get unique values and their count
for (int val : myInts)
++uniqueValues[val];
//Output:
for (const auto & val : uniqueValues)
std::cout << val.first << " occurs " << val.second << " times." << std::endl;
在这种情况下,它不一定是
std::unordered_set
。