【问题标题】:Needed: C++ class for maintaining a 1-dimensional list of extents需要:用于维护一维范围列表的 C++ 类
【发布时间】:2012-12-20 21:26:04
【问题描述】:

我正在寻找一个可以维护一维范围列表的 C++ 类。

每个范围都定义为一个(start,len) 对。

我希望能够向列表中添加其他扩展区并自动合并它们。也就是说,如果列表中有(0,5)(10,5),并且添加了(5,5),则新列表应该只包含(0,15)

范围永远不会从列表中删除。

这样的事情存在吗?

谢谢。

【问题讨论】:

    标签: c++ algorithm stl-algorithm


    【解决方案1】:

    您正在寻找 Boost.Icl。它完全符合您的描述。

    http://www.boost.org/doc/libs/1_52_0/libs/icl/doc/html/index.html

    【讨论】:

    • 我不清楚 Boost.lcl 是否会合并相邻的范围。你确定它确实如此吗?我们将拥有数十万个连续范围。
    • 会的。我一直以这种方式使用它。查看此页面:boost.org/doc/libs/1_52_0/libs/icl/doc/html/…
    • 太棒了。谢谢!这正是我所需要的。
    【解决方案2】:

    这是一个简单间隔容器的示例实现:

    #include <iostream>
    #include <vector>
    #include <memory>
    #include <algorithm>
    
    using std::vector;
    using std::pair;
    using std::make_pair;
    
    typedef pair<int, int> interval;    
    
    struct interval_container
    {
        void add(int start, int len)
        {
            _data.emplace_back( make_pair(start, len) );
        }
    
        void consolidate()
        {
            // sort intervals first by start then by length
            std::sort(_data.begin(), _data.end());
    
            // create temp data
            vector<interval> consolidated;
    
            // iterate over all sorted intervals
            for(const interval& i : _data)
            {
                int start = i.first;
                int len = i.second;
    
                // special case: first interval
                if (consolidated.empty())
                {
                    consolidated.emplace_back(i);
                }
                // all other cases
                else
                {
                    // get last interval in the consolidated array
                    interval& last = consolidated.back();
                    int& last_start = last.first;
                    int& last_len = last.second;
    
    
                    // if the current interval can be merged with the last one
                    if ((start >= last_start) and (start < (last_start + last_len)))
                    {
                        // merge the interval with the last one
                        last_len = std::max(last_len, (start + len - last_start));
                    }
                    // if the current interval can't be merged with the last one
                    else
                    {
                        consolidated.emplace_back(i);
                    }
                }
            }
    
            // copy consolidated data
            _data = consolidated;
        }
    
    
        vector<interval>& data() { return _data; }
    
    private:
        vector<interval> _data;
    };
    
    
    int main()
    {
        interval_container intervals;
    
        intervals.add(0, 2);
        intervals.add(1, 3);
        intervals.add(5, 3);
    
        intervals.consolidate();
    
        int c(0);
        for(interval i : intervals.data())
        {
            std::cout << (c++) << ": from " << i.first << " to " << (i.first + i.second) << std::endl;
        }
    }
    

    【讨论】:

    • 谢谢。问题 --- 我已经看到一大群人用 struct 定义类,就像你在这里看到的那样,而不是使用正确的 C++ 类声明。为什么要将类定义为结构?
    • 请参阅here,了解有关结构和类之间差异的 SO 问题。就个人而言,我这样做是因为我总是在类的顶部声明公共方法,并且我不想总是输入“public:”。随着时间的推移,这已成为一种习惯。
    猜你喜欢
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多