【问题标题】:Efficient data structure for finding non-overlapping range containing a number用于查找包含数字的非重叠范围的有效数据结构
【发布时间】:2011-12-14 21:22:59
【问题描述】:

用于存储范围起点和终点的数据结构。

rangename      start     end

range1          10        11

range2          20        22

range3          0         5

现在,如果我必须找到可能存在数字“x”的范围。

在 c++ 中存储它的有效方法是什么?

我正在尝试使用地图。但是然后搜索以查找范围可能很昂贵(我不确定)。建议一个好的数据结构。

我应该能够找到该元素是否存在于某个范围内。范围不应混合和匹配,并且没有相邻或其他界限。

如果我需要查找元素 3,它存在于范围 3 中,但元素 12 根本不存在。仅仅循环不是一种有效的方式。

【问题讨论】:

  • 您的范围是否重叠?找到任何特定数字的范围是否会产生唯一的答案?
  • 您将拥有多少个范围?他们多久会改变一次?值的总人口有多大(即 max-min)?
  • 抱歉问题中的错误。范围不会重叠(我的印象是它可能。)并且值的数量最多为 100 到 200 条记录。

标签: c++ search data-structures range


【解决方案1】:

(自从提问者澄清他的范围不重叠后,我已经更改了这个答案。)

如果范围集没有改变,您可以使用排序向量和二进制搜索,如 ravenspoint 的回答中所建议的那样。

如果范围集随时间变化,您可能仍使用排序向量,或者您可能希望使用std::map。在这种情况下,您需要同时尝试两者,看看哪个更快。

【讨论】:

  • 我仍然发现实际查找某个元素是否存在于某个范围内的问题。问题是它是否应该严格地存在于该范围内的任何人中?!没有混合和匹配范围。
【解决方案2】:

vector< pair< int>> 存储已排序,以便您可以进行二进制搜索?

【讨论】:

    【解决方案3】:

    假设范围不重叠:

    将每个范围存储在一个简单的结构中

    range {
      int low;
      int high;
      string name;
    }
    

    将范围存储在排序向量中,按低。

    使用二分查找最大的小于目标的最小值。

    【讨论】:

    • 他的 range1 和 range3 示例重叠。
    • 显然它们不重叠。这个问题令人困惑。我已经编辑了问题,所以示例不重叠
    • 抱歉问题中的错误。你在我之前编辑过。我没有注意到重叠。
    【解决方案4】:

    只需将所有值、开始和结束都转储到向量或数组中,然后对其进行排序。由于范围不重叠,一旦对数组进行排序,您将拥有开始、停止、开始、停止等。然后,您可以使用二进制搜索来查找向量的索引。那么它只是奇数还是偶数的问题

    假设,您正在从流中获取范围

    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 range\n";
        }
     }
    

    二分查找定义为

     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);
     }
    

    希望我没有搞砸二分搜索,但它的设计方式是,如果找不到该值,则返回下一个最大值的索引。

    【讨论】:

    • 我需要找出元素是否存在于一个范围内,它不应该混合和匹配,它应该严格地存在或不存在。
    【解决方案5】:

    为什么不使用 B+ 树? 使用 B+ 树,扇出会很小,搜索也会很快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 2020-08-26
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      相关资源
      最近更新 更多