代码之家  ›  专栏  ›  技术社区  ›  sdg

通过范围键保存值的结构

  •  4
  • sdg  · 技术社区  · 15 年前

    我有一个范围键,它是双精度的,还有一个值

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

    这样,搜索1.23应该返回值1,依此类推。

    编辑:谢谢大家。假设本例中的范围是连续的且不重叠的,那么使用上界就可以了。感谢您提供的系列解决方案,这些解决方案已存档备查。

    3 回复  |  直到 15 年前
        1
  •  3
  •   Mykola Golubyev    15 年前
    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
  •  2
  •   Mark Ransom    15 年前

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

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

    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
  •  1
  •   John Dibling    15 年前

    沿着这些思路做点什么怎么样:

    #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'