我正在制定一项要求,其中请求应具有从-2到-101的唯一编号,即一次只有100个请求。如果在给定时间有超过100个请求,那么我应该发送错误。最初我没有要求。一旦我发出请求,我将采用唯一的数字说-2,-3等等。这里的要求是我可能从客户端获取命令没有向服务器发送请求例如-2所以我应该删除这个请求,我应该重用这个号码以备将来请求。
在C ++中实现此功能的最佳方法是什么?
另外,我不应该使用Boost。
答案 0 :(得分:3)
扩展我的std::bitset
评论:
您可以使用id作为bitset的索引和值(true/false
)作为id的可用性。
class IdStorage {
const int N = 100;
std::bitset<N> ids;
bool allIdsUsed() {
return ids.all();
}
int getId() {
if(allIdsUsed())
throw "Error";
for(int i = 0; i < N; ++i )
if(ids.test(i))
return i - 2;
}
void releaseId(int i) {
ids.set(i + 2);
}
}
请注意,在课堂上键入此内容,不在我的脑海中。查看documentation
答案 1 :(得分:2)
您必须至少维护一组未使用的ID。另外,我会抛出一个查找表来验证是否发出了一个id(为了健壮性)。对于两者,我建议使用std::vector
,而不是列表。
首先,将未使用的集合存储在std::vector<int>
中,您可以很容易地初始化它:
class IdStore {
private:
std::vector<int> unused;
static int const MIN_ID = -101;
static int const MAX_ID = -2;
public:
IdStore::IdStore()
: unused(MAX_ID - MIN_ID + 1) {
for (auto i = 0; i <= MAX_ID-MIN_ID; ++i) {
unused[i] = i;
}
}
int getId();
void releaseId(int);
};
此外,您可能希望跟踪使用过的ID,以便验证它们是否已分发;我使用了std::vector<bool> used;
成员,您可以使用used(MAX_ID - MIN_ID +1)
初始化,因为其值最初都默认为false
。当然,您可以将used
设为bitset
,但请注意,这需要在编译时知道从MIN_ID
到MAX_ID
的距离。
从那里分发东西很简单:
int IdStore::getId() {
if (unused.empty())
throw "error"; // put something better here
auto r = unused.back();
used[r] = true;
unused.pop_back();
return MIN_ID + r;
}
然后发布它们:
void IdStore::releaseId(int id) {
if (id < MIN_ID || id > MAX_ID)
throw "error"; // put something better here
id -= MIN_ID;
if (!used[id])
throw "error"; // put something better here
used[id] = false;
unused.push_back(id);
}
请注意,不会发生重新分配!与使用列表的方法相反,向量将keep its size,而getId
和releaseId
都不需要对malloc
或free
进行昂贵的调用。
答案 2 :(得分:1)
只有100个数字可能没有明显的性能差异,您可以使用集合或数组;像id_used[100]
这样的普通旧数组可能会在性能测量中获胜。
如果您需要可扩展的解决方案,请尝试使用“free-set”和“used-set”,其中包含可供使用的自由设置存储ID,以及已使用id的已使用集合。使用id后,将其存储回自由集。
对于允许的id与并发使用的足够大的比率,仅使用“used-set”,并使用拒绝采样来查找空闲ID:
do {
id = generate_id();
} while(std::end != used_set.find(id));
无论如何,没有明确的答案。
答案 3 :(得分:0)
我没有编译它,但它应该是这样的:
std::list<int> list;
for(int i=start; i<=end; ++i)
list.insert(i);
//when get Id request
Id2send = list.first();
list.remove(list.first());
//when delete id request
list.remove(id);
//when add id request (this happens when an id is freed or other times)
list.add(id);