用于查找包含数字的非重叠范围的有效数据结构
Efficient data structure for finding non-overlapping range containing a number
一个数据结构,用于存储范围的起始点和端点。
rangename start end
range1 10 11
range2 20 22
range3 0 5
现在,如果我必须找到一个数字'x'可能存在的范围。
在c++中如何有效地存储它?
我正在尝试使用地图。但是搜索范围可能会很昂贵(我不确定)。建议一个好的数据结构。
我应该能够找到元素是否存在于一个范围内。范围不应混合和匹配,也没有相邻或其他边界。
如果我需要查找元素3,它在范围3中,但是元素12根本不存在。只是循环遍历并不是有效的方法。
(由于提问者澄清了他的范围不重叠,我已经更改了这个答案)
如果范围集没有改变,您可以使用排序向量和二进制搜索,如ravenpoint的答案所建议的。
如果范围集随时间变化,您可能仍然使用排序向量,或者您可能希望使用std::map
。您需要尝试两种方法,看看哪种方法在这种情况下更快。
vector< pair< int>>
存储排序,所以你可以二进制搜索也许?
假设范围不重叠:
将每个范围存储在一个简单的结构
中range {
int low;
int high;
string name;
}
将范围存储在一个有序的向量中,按low。
只是转储所有的值,开始和结束到一个向量或数组,然后排序。由于范围不重叠,一旦数组被排序,你将有start,stop, start,stop等等。然后,您可以使用二分搜索来查找向量的索引。那么问题就变成是奇数还是偶数了
假设您从流
获得范围vector<int> ranges;
int n;
while(in >> n){
ranges.push_back(n);
}
sort(ranges.begin(),ranges.end())
int x;
cout <<"please enter a value to search for: ";
cin >> x;
int index = binary_search(x,ranges);
if(index % 2){
cout << "The value " << x << "is in the range of "
<< ranges[index-1] << " to " << ranges[index] << endl;
}else{
if(ranges[index] == x){
cout << "The value " << x << "is in the range of "
<< ranges[index] << " to " << ranges[index+1] << endl;
}
else{
cout << "Value " << x << " is not in any rangen";
}
}
,其中二分查找将定义为
int binary_search(int x, vector<int>& vec, int s = 0; int f = -1){
if(f == -1)f=vec.size();
if(s >= f) return s;
int n = (f-s)/2 + s;
if(vec[n] == x)return n;
if(vec[n] < x)return binary_search(x,vec,s,n-1);
return binary_search(x,vec,n+1,f);
}
希望我没有搞砸二进制搜索,但它的设计方式是,如果没有找到值,则返回下一个最大值的索引。
为什么不用B+树呢?使用B+树,扇形输出会很小,搜索也会很快。
相关文章:
- 在函数内创建的对象的范围 - 如果在函数外部存储和访问引用,它们是否有效?
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- "using namespace"子句在什么范围内有效?
- 如果一个对象是在本地创建的,并在C++中作为异常抛出,那么本地对象如何在其范围之外有效,即在 catch 块中?
- 这是有效的C++代码吗?(在声明范围之外使用本地类型)
- 在某些范围更新后获取整数数组的最终状态的有效算法是什么?
- C++数组超出范围访问以计算指针有效?
- 在相应的承诺离开范围后有效使用未来
- 具有从特定范围的随机数初始化特征矩阵或向量初始化特征矩阵或向量的有效方法
- 如何有效地获得给定范围内的除数和
- 有没有有效的方法可以从现在开始生成从范围到 10 天的随机date_time
- 如何在大数组中最有效地增加指定范围内的值,然后找到最大值
- C++中数组范围内的有效元素计数
- 有效的迭代器范围从堆栈上的char
- 如何检测ptr在引用超出范围后是否仍在引用有效引用
- 在 ipv6 链接范围单播 udp 客户端-服务器中应用 boost::asio::ip::udp,有时有效,但有时无效
- 在循环范围之外声明参数是否更有效?
- 这是从连续的单词序列中提取任意范围的位的最有效方法
- 按元素添加两个范围的惯用和有效方法
- 将 uint8 转换为范围为 0-1 的浮点数的最有效方法