是否有用于存储离散间隔的集合

Is there a collection for storing discrete intervals?

本文关键字:集合 用于 存储 是否      更新时间:2023-10-16

我需要将离散范围存储在一个集合中,在插入时连接相邻的范围。STL中是否有已经具有此类功能的结构?

我已经尝试了 boost::intervals,但它很重,对于我正在尝试做的事情来说有点矫枉过正。

例如,假设集合为空,并插入了以下元素:

[64, 96]
[0, 4]
[11, 15]
[5, 10]

间隔集的预期内容应如下所示:

[0, 15]
[64, 96]
您希望

合并间隔以防它们彼此相邻,这一事实使您的任务比建议的间隔树方法容易得多。

相反,您可以使用Some programmer dude提出的数据结构,并非常快速地推出自己的实现。在这里,我提供了一个可能的实现:

class IntervalSet {
    std::map<int, int> _intervals;
public:
    void Add(int smaller, int bigger) {
        const auto next = _intervals.upper_bound(smaller);
        if (next != _intervals.cbegin()) {
            const auto prev = std::prev(next);
            if (next != _intervals.cend() && next->first <= bigger + 1) {
                bigger = next->second;
                _intervals.erase(next);
            }
            if (prev->second + 1 >= smaller) {
                smaller = prev->first;
                _intervals.erase(prev);
            }
        }
        _intervals[smaller] = bigger;
    }
    const auto& Intervals() const { return _intervals; }
    bool IsInsideInterval(int v) const {
        const auto suspectNext = _intervals.upper_bound(v);
        const auto suspect = std::prev(suspectNext);
        return suspect->first <= v && v <= suspect->second;
    }
};

小测试:

IntervalSet is;
is.Add(64, 96);
is.Add(0, 4);
is.Add(11, 15);
is.Add(5, 10);
for (const auto p : is.Intervals()) std::cout << "(" << p.first << ", " << p.second << ") ";

(0, 15( (64, 96(

它也适用于相交间隔:

IntervalSet is;
is.Add(0, 10);
is.Add(5, 15);
is.Add(10, 20);
for (const auto p : is.Intervals()) std::cout << "(" << p.first << ", " << p.second << ") ";

(0,20(

这是一个众所周知的问题。有一个维基百科页面,关于您的问题的可能解决方案。当然,在C++STL中,你可以使用std::map来实现一个基于朴素方法的解决方案,维基百科中解释过,因为地图是红黑树,是一种二叉搜索树。