通过范围键保存值的结构

发布于 2024-07-18 06:48:28 字数 403 浏览 2 评论 0原文

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

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

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

搜索 1.23 应返回 value1,依此类推。

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

编辑:谢谢大家。 鉴于本例中的范围应该是连续且不重叠的,因此使用 upper_bound 就可以正常工作。 也感谢您提供 Range 类解决方案,它们已归档以供将来参考。

I need a structure to hold a value based on a key that has a range.
My implementation is C++, so any STL or Boost would be excellent.

I have as range-key, which are doubles, and value

  • [0,2) -> value1
  • [2,5) -> value2
  • [5,10) -> value3
  • etc

Such that a search of 1.23 should return value1, and so on.

Right now I am using a vector containing all three parts, key1/key2/value, with custom searching, but it feels like there should be a cleaner structure.

Edit: Thanks all. Given the ranges in this case are supposed to be contiguous and non-overlapping, the use of upper_bound will work just fine. Thanks for the class Range solutions as well, they are filed away for future reference.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

下壹個目標 2024-07-25 06:48:28
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;
}
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;
}
┈┾☆殇 2024-07-25 06:48:28

如果您的范围是连续且不重叠的,则应使用 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);

If your ranges are contiguous and non-overlapping, you should use std::map and the upper_bound member function. Or, you could use a sorted vector with the upper_bound algorithm. Either way, you only need to record the lowest value of the range, with the upper part of the range being defined by the next higher value.

Edit: I phrased that confusingly, so I decided to provide an example. In coding the example, I realized you need upper_bound instead of lower_bound. I always get those two confused.

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);
飞烟轻若梦 2024-07-25 06:48:28

沿着这些思路怎么样:

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

How about something along these lines:

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

... program output:

[0, 5) = 'First'
[5, 10) = 'Second'
[10, 15) = 'Third'
--------------------------------------
[0, 5) = 'Revised First'
[5, 10) = 'Second'
[10, 15) = 'Third'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文