Набор типа класса - PullRequest
       5

Набор типа класса

1 голос
/ 03 января 2011

Можете ли вы написать перегруженную функцию для удаления объекта DATA из установленного, например: s.erase(4) Здесь 4 может быть значением или x или y.

struct DATA
{
   DATA(int X, int Y):x(X), y(Y){}
   int x;
   int y;

   bool operator < (const DATA &d) const
   {
       return x < d.x || (x == d.x && y < d.y);
   }
};


int main()
{
   set <DATA> s;

   for (int i = 0; i < 5; i++)
      s.insert(DATA(i, i+5));

   s.erase(0) // remove where x = 0
}

Ответы [ 5 ]

2 голосов
/ 03 января 2011

Конечно!

Вы можете написать функтор для поиска элементов множества, где ЛИБО х или у 4, и стереть такие элементы.Вам нужно, чтобы boost::bind упростила привязку:

#include <set>
#include <algorithm>
#include <boost/bind.hpp>

struct Foo {
    int x, y;

    bool operator<(const Foo& rhs) const {
        return (x < rhs.x || (x == rhs.x && y < rhs.y));
    }

    bool hasValue(int v) const {
        return (x == v || y == v);
    }
};

int main()
{
    std::set<Foo> s;
    Foo a = {4,2}; s.insert(a);
    Foo b = {3,4}; s.insert(b);

    std::cout << s.size() << std::endl; // will output: "2"

    std::set<Foo>::iterator it;

    // Search for an element with the given value '4' in either x or y
    // Erase first matching element found, if any
    // (our first element, which has x=4)
    it = std::find_if(s.begin(), s.end(), boost::bind(&Foo::hasValue, _1, 4));
    if (it != s.end())
        s.erase(it);

    std::cout << s.size() << std::endl; // will output: "1"

    // Erase the next one
    // (our second element, which has y=4)
    it = std::find_if(s.begin(), s.end(), boost::bind(&Foo::hasValue, _1, 4));
    if (it != s.end())
        s.erase(it);

    std::cout << s.size() << std::endl; // will output: "0"
}

Не был тщательно протестирован на опечатки.

Вы можете получить те же функции без повышения, используя статическую функциюкоторый принимает Foo* в качестве аргумента.

2 голосов
/ 03 января 2011
0 голосов
/ 03 января 2011

Как насчет std::map контейнера?Вы можете использовать x или y в качестве key_type и сохранить неключевые значения в классе как value_type.

0 голосов
/ 03 января 2011

Конечно, вы можете изменить структуру данных для работы с более крупным целочисленным типом и использовать сдвиг битов для упаковки пары меньших целочисленных типов. Однако в более общем смысле, то нет.Существуют контейнеры с несколькими индексами, но std :: set не является одним из них.

0 голосов
/ 03 января 2011

Нет;ваш набор упорядочен по X, вы не можете также упорядочить набор по Y, чтобы удалить его.Вам нужно будет перебрать набор, чтобы найти элементы, которые вы хотите удалить, а затем удалить их, как вы обычно удаляете из набора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...