Как я могу разделить «Сегмент» на два «Сегмента»?C ++ - PullRequest
0 голосов
/ 25 июня 2018

с учетом следующих классов:

#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? while:
если typeS == OPEN так: (left,right).
если typeS == ЗАКРЫТЬ так: [left,right].
, если typeS == CLOSE_LEFT, так: [left,right).
, если typeS == CLOSE_RIGHTso: (left,right].

и SegCollection описывает набор сегментов так, что:
SegCollection no содержит два одинаковых сегмента, и no не содержит двух сегментов с пересечением (вместо них будет объединение их), и даже no не содержит два сегмента, напримерчто: [1,4) и [4,5) (например), но оно будет содержать [1,5).

Как я могу реализовать operator-() для SegCollection, который удаляет сегмент из SegCollection так, что: этот сегмент должен быть не в SegCollection, а во всех точках (из всех сегментов в SegCollection), которые существуют в SegCollection и в удаленном сегменте будут удалены из сегментов, существующих в SegCollection.

Например: дано: [1,7] , [9,12], если мы удалим (2,5), то получим: [1,2] , [5,7] , [9,12].

Я не знаю (я думал об этом несколько часов ..), как мне поступить, если мне нужно разделить сегмент после удаления сегмента (например, [1,7] в примере, который изменился на[1,2] , [5,7])?

Примечание. Сегмент - это класс шаблона, поскольку он может быть из (int, int), (float, float), например

1 Ответ

0 голосов
/ 25 июня 2018

Этот совет может помочь.

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 из-за причин доступа (вы можете покинуть класс, но вам нужно предоставить некоторые методы получения, чтобы иметь доступ к закрытым членам)

#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;
    }
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...