如何将“细分”分为两个“细分”? C ++

时间:2018-06-25 17:53:10

标签: c++ class c++11 vector

提供了以下课程:

#include <vector>

using std::vector;

enum TypeSeg {
    OPEN, CLOSE, CLOSE_LEFT, CLOSE_RIGHT
};

template<class T>
class Segment {
    T left;
    T right;
    TypeSeg typeS;
public:
    Segment(T left, T right, TypeSeg typeS) :
            left(left), right(right), typeS(typeS) {
    }
    //.....
};

template<class T>
class SegCollection {
    vector<Segment<T>> segments;
public:
//.....
};

以便该细分在以下时间描述细分?left, right?
如果typeS == OPEN,则为(left,right)
如果typeS == CLOSE,则为[left,right]
如果typeS == CLOSE_LEFT,则:[left,right)
如果typeS == CLOSE_RIGHTso:(left,right]

和SegCollection描述了段的集合,以便:
SegCollection no包含两个相同的段,no包含两个相交的段(它将包含它们的并集),甚至no也不包含两个段,例如:[1,4)[4,5)(例如),但是,它将包含[1,5)

如何为SegCollection实现operator-()以便从SegCollection中删除段,以便:该段不必一定在SegCollection中,而是在SegCollection 中存在的所有点(来自SegCollection中的所有段)和删除的段中的将从SegCollection中存在的段中删除。

例如:给定:[1,7] , [9,12],如果我们删除(2,5),那么我们将得到:[1,2] , [5,7] , [9,12]

我不知道(我好几个小时都在想这件事。)在需要删除段(如示例中的[1,7],然后更改为{ {1}})?

注意:Segment是模板类,因为它可以来自(int,int),(float,float)例如

1 个答案:

答案 0 :(得分:0)

此技巧可能会有所帮助。

template<typename T>
class SegCollection {
    vector<Segment<T>> segments;
public:
    void push_back(Segment<T> seg)
    {
        segments.push_back(seg);
    }

    const SegCollection& operator-(const Segment<T> seg) 
    {  
        // implement some rules that recognize field 
        // TypeSeg and depending on it, changing segments' content
        // ...
        return *this;
    }
}

下面找到您的假设的简短应用。由于访问原因,我已将类更改为struct(您可以退出课程,但需要提供一些getter才能访问私有成员)

#include <vector>
#include <algorithm>
using std::vector;

enum TypeSeg {
    OPEN, CLOSE, CLOSE_LEFT, CLOSE_RIGHT
};

template<typename T>
struct Segment {
    T left;
    T right;
    TypeSeg typeS;

    Segment(T left, T right, TypeSeg typeS) :
            left(left), right(right), typeS(typeS) {
    };
};

template<typename T>
struct SegCollection {

    vector<Segment<T>> segments;

    void push_back(Segment<T> seg)
    {
        segments.push_back(seg);
    }

    const SegCollection& operator-(const Segment<T> seg) 
    { 
        //Find segment that could be divided
        auto it = std::find_if(segments.begin(), segments.end(),
                          [&seg](auto i){ 
                              if (i.left <= seg.left)
                                 if (seg.right <= i.right) 
                                     return true;
                              return false;
                        });

        //If not found, return *this
        if (it == segments.end())
        {
            std::cout << "Cannot do this, Bro." << std::endl;
            return *this;
        }

        //Set boundaries for new segments
        int new_right = it->left + seg.left - it->left;            
        int new_left = seg.right;

        // Here you have to apply other conditions
        // I have used only one case - as you have mentioned in your post
        if (seg.typeS == OPEN)
        {
            Segment<T> seg_first(it->left, new_right, CLOSE);
            Segment<T> seg_second(new_left, it->right, CLOSE);
            *it = seg_second;
            this->segments.insert(it, seg_first);   

        } 

        return *this;
    }
};