【问题标题】:Structure to hold value by ranged key通过范围键保持值的结构
【发布时间】:2009-04-21 16:13:11
【问题描述】:

我需要一个结构来保存基于具有范围的键的值。 我的实现是 C++,所以任何 STL 或 Boost 都可以。

我有作为范围键,它们是双精度数和值

  • [0,2) -> 值1
  • [2,5) -> 值2
  • [5,10) -> 值3

这样搜索 1.23 应该返回 value1,以此类推。

现在我正在使用一个包含所有三个部分的向量,key1/key2/value,以及自定义搜索,但感觉应该有一个更清晰的结构。

编辑:谢谢大家。鉴于这种情况下的范围应该是连续的且不重叠的,使用 upper_bound 就可以了。也感谢类 Range 解决方案,它们已归档以备将来参考。

【问题讨论】:

    标签: c++ stl


    【解决方案1】:
    class Range
    {
    public:
        Range( double a, double b ):
            a_(a), b_(b){}
        bool operator < ( const Range& rhs ) const
        {
            return a_ < rhs.a_ && b_ < rhs.b_;
        }
    private:
        double a_;
        double b_;
    };
    int main()
    {
        typedef std::map<Range, double> Ranges;
        Ranges r;
    
        r[ Range(0, 2) ] = 1;
        r[ Range(2, 5) ] = 2;
        r[ Range(5, 10) ] = 3;
    
        Ranges::const_iterator it1 = r.find( Range( 2, 2 ) );
        std::cout << it1->second;
    
        Ranges::const_iterator it2 = r.find( Range( 2, 3 ) );
        std::cout << it2->second;
    
        Ranges::const_iterator it3 = r.find( Range( 6, 6 ) );
        std::cout << it3->second;
    
        return 0;
    }
    

    【讨论】:

      【解决方案2】:

      如果您的范围是连续且不重叠的,您应该使用 std::map 和 upper_bound 成员函数。或者,您可以使用带有 upper_bound 算法的排序向量。无论哪种方式,您只需要记录范围的最小值,范围的上部由下一个更高的值定义。

      编辑:我的措辞令人困惑,所以我决定提供一个例子。在编写示例代码时,我意识到您需要的是 upper_bound 而不是 lower_bound。我总是把这两个弄糊涂。

      typedef std::map<double, double> MyMap;
      MyMap lookup;
      lookup.insert(std::make_pair(0.0, dummy_value));
      lookup.insert(std::make_pair(2.0, value1));
      lookup.insert(std::make_pair(5.0, value2));
      lookup.insert(std::make_pair(10.0, value3));
      MyMap::iterator p = lookup.upper_bound(1.23);
      if (p == lookup.begin() || p == lookup.end())
          ...; // out of bounds
      assert(p->second == value1);
      

      【讨论】:

      • 那不是,“范围的上半部分由下一个较低的值定义。”?
      【解决方案3】:

      这样的事情怎么样:

      #include "stdafx.h"
      #include <iostream>
      #include <string>
      #include <map>
      #include <algorithm>
      #include <sstream>
      
      
      class Range
      {
      public:
          Range(double lower, double upper) : lower_(lower), upper_(upper) {};
          Range(const Range& rhs) : lower_(rhs.lower_), upper_(rhs.upper_) {};
          explicit Range(const double & point) : lower_(point), upper_(point) {};
          Range& operator=(const Range& rhs) 
          { 
              lower_ = rhs.lower_; 
              upper_ = rhs.upper_; 
              return * this; 
          }
      
          bool operator < (const Range& rhs) const
          {
              return upper_ <= rhs.lower_;
          }
      
          double lower_, upper_;
      };
      
      typedef std::string Thing;
      typedef std::map<Range, Thing> Things;
      
      
      std::string dump(const std::pair<Range,Thing> & p)
      {
          stringstream ss;
          ss << "[" << p.first.lower_ << ", " << p.first.upper_ << ") = '" << p.second << "'" << endl;
          return ss.str();
      }
      
      int main()
      {
          Things things;
          things.insert( std::make_pair(Range(0.0, 5.0), "First") );
          things.insert( std::make_pair(Range(5.0, 10.0), "Second") );
          things.insert( std::make_pair(Range(10.0, 15.0), "Third") );
      
          transform( things.begin(), things.end(), ostream_iterator<string> (cout,""), dump );
      
          cout << "--------------------------------------" << endl;
      
          things[Range(1.5)] = "Revised First";
      
          transform( things.begin(), things.end(), ostream_iterator<string> (cout,""), dump );
      
      
          return 0;
      }
      

      ...程序输出:

      [0, 5) = 'First'
      [5, 10) = 'Second'
      [10, 15) = 'Third'
      --------------------------------------
      [0, 5) = 'Revised First'
      [5, 10) = 'Second'
      [10, 15) = 'Third'
      

      【讨论】:

        猜你喜欢
        • 2021-03-25
        • 1970-01-01
        • 1970-01-01
        • 2018-02-17
        • 2018-12-04
        • 2013-05-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-11
        相关资源
        最近更新 更多