在C++ (Windows上)中,我需要保留一组int:结对,其中开始值是唯一的(我们不需要关注这个问题)。所需行动如下:
基本的解决方案是简单地保持一组对。为了进行检索,我们将对集合进行顺序迭代以检查。这是O(n)。
我在找更好的解决办法。我目前看到两个候选数据结构:
排序向量:优点:可以自定义二进制搜索以支持检索操作。这是O(logn) Cons:如何有效地插入新的对以保持排序顺序。如何避免O(nlogn)的重新排序成本?
集合:优点:使用标准插入方法容易插入。这是O(1)?缺点:如何避免顺序搜索?如何比O(n)做得更好?
谢谢你的建议。
我也对任何其他能够有效支持上述两个操作的结构开放(第一个标准是速度,第二个是内存)。
发布于 2012-04-17 20:41:07
目前还不清楚范围是否可以重叠,但如果它们不能,那么这应该可以工作。我包含了一个包含测试的完整示例。
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <map>
struct RangeContainer {
typedef std::map<int,int> RangeMap;
typedef std::pair<int,int> Range;
void insert(const Range &range)
{
range_map.insert(range);
}
Range find(const Range &x) const
{
RangeMap::const_iterator iter = range_map.upper_bound(x.second);
if (iter==range_map.begin()) {
return invalidRange();
}
--iter;
Range y = *iter;
if (y.first<x.first && x.second<y.second) {
return y;
}
return invalidRange();
}
static Range invalidRange()
{
return Range(INT_MAX,INT_MIN);
}
RangeMap range_map;
};
static void test1()
{
RangeContainer c;
typedef RangeContainer::Range Range;
c.insert(Range(1,10));
c.insert(Range(20,30));
assert(c.find(Range(-5,-4))==c.invalidRange());
assert(c.find(Range(1,10))==c.invalidRange());
assert(c.find(Range(2,9))==Range(1,10));
assert(c.find(Range(2,10))==c.invalidRange());
assert(c.find(Range(11,19))==c.invalidRange());
assert(c.find(Range(21,29))==Range(20,30));
assert(c.find(Range(20,29))==c.invalidRange());
assert(c.find(Range(21,30))==c.invalidRange());
assert(c.find(Range(35,40))==c.invalidRange());
}
int main(int argc,char **argv)
{
test1();
return EXIT_SUCCESS;
}
https://stackoverflow.com/questions/10202275
复制相似问题