我需要一个具有以下要求的集合(如果重要的话,在目标C中):
哈希集可行,但NSMutableSet类是抽象的。我不知道如何编写NSMutableSet类,但我认为动态增长/收缩的哈希集合适合,因为负载率具有保证范围,因此随机元素功能可以通过随机选择一个桶来实现并遍历存储桶直到找到非空桶,然后从该存储桶中选择一个随机元素。这将是很好的,因为它会选择一个随机元素恒定时间,但我不想重新发明轮子。有没有人有任何建议或图书馆指出我。
提前致谢。
答案 0 :(得分:1)
我最近偶然发现了同样的问题。这就是我想出来的
#include <unordered_set>
#include <iostream>
using namespace std;
int main() {
unordered_set<int> u;
int ins = 0;
for (int i=0; i<30; i++) { // something to fill the test set
ins += i;
ins %= 73;
u.insert(ins);
}
cout << "total number of buckets: " << u.bucket_count() << endl;
for(size_t b=0; b<u.bucket_count(); b++) //showing how the set looks like
if (u.bucket_size(b)) {
cout << "Bucket " << b << " contains: ";
unordered_set<int>::local_iterator lit;
for (lit = u.begin(b); lit != u.end(b);) {
cout << *lit;
if (++lit != u.end(b))
cout << ", ";
}
cout << endl;
}
cout << endl;
int r = rand() % u.bucket_count();
while (u.bucket_size(r) == 0) // finding nonempty bucket
r = (r + 1) % u.bucket_count(); // modulo is here to prevent overflow
unordered_set<int>::local_iterator lit = u.begin(r);
if (u.bucket_size(r) > 1) { // if bucket has more elements then
int r2 = rand() % u.bucket_size(r); // pick randomly from them
for (int i = 0; i < r2; i++)
lit++;
}
cout << "Randomly picked element is " << *lit << endl;
cin.ignore();
return 0;
}
现在重新讨论问题:
但是,如果你的集合增长然后迅速收缩,那么在集合为空之前就没有重复,所以你可能想要执行检查并最终重新散列。
if(u.load_factor()&lt; 0.1) u.rehash(u.size());
这将检查该集合是否至少满10%,如果不满,则重新散列,因此集合的大小适合存储当前元素数量。 (通常新尺寸等于2的较小功率,大于尺寸)
答案 1 :(得分:0)
由于您的constant
实际上是log n
,我建议您自己推广 B-tree 。然后你有:
- (id)randomObject {
Your_Branch_Type* branch = your_root;
NSUInteger randomIndex = RANDOM_INTEGER_UP_TO(count);
while (!branch.final)
if (branch.left.count >= randomIndex) {
branch = branch.left;
} else {
branch = branch.right;
}
return branch.object;
}