提供了以下课程:
#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)例如
答案 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;
}
};