Поиск на карте STL - PullRequest
       2

Поиск на карте STL

0 голосов
/ 03 декабря 2018

У меня есть карта с указателем структуры в качестве ключа.

std :: map ;

struct struct1 {int x;char a [10];};struct struct2 {int x;};

Ключ - указатель на struct1.struct1 имеет член с именем x.

Я должен искать карту по элементу x struct1.

Можно ли выполнять поиск, не просматривая все элементы на карте?

Я попробовал приведенный ниже код, но он не работает.

include <iostream>
#include <map>
struct struct1 { int x; char a[10]; };
struct struct2{ int x; };

bool operator<(const struct1 & fk1, const struct1& fk2) { 
    return fk1.x < fk2.x;
}
int main()
{  
    std::map<struct1 *, struct2> m;
    struct1 *f1 = new struct1();
    f1->x =1;
    strcpy(f1->a,"ab");
    struct2 l1;
    l1.x=10;
    m.insert(std::make_pair(f1, l1));

    struct1 fk1;
    fk1.x=1;
    std::map<struct1 *, struct2>::iterator x = m.find(&fk1);
    if(x != m.end())
    {
        std::cout << x->first->x <<std::endl;
        std::cout << x->first->a <<std::endl;
    }


   if(f1!=NULL)
   delete f1;
return 0;
}

Ответы [ 3 ]

0 голосов
/ 03 декабря 2018

Давайте расширим параметры по умолчанию m:

std::map<struct1 *, struct2, std::less<struct1 *>, std::allocator<std::pair<const struct1 *, struct2> >

Мы увидим, что компаратором карты является std::less<struct1 *>, который будет проверять числовое значение аргументов указателя.Он не вызывает struct1::operator <.

Если у вас есть компилятор C ++ 14, и вы хотите искать его с помощью члена int, вы должны использовать пользовательский компаратор, который прозрачный , например

struct struct1_less
{
    typedef void is_transparent;
    // C++11 and later: using is_transparent = void;

    // compare pointers
    bool operator()(const struct1* lhs, const struct1* rhs) const { return lhs->x < rhs->x; }
    // compare with int
    bool operator()(const struct1* lhs, int rhs) const { return lhs->x < rhs; }
    bool operator()(int lhs, const struct1* rhs) const { return lhs < rhs->x; }
};

Используется как

typedef std::map<struct1 *, struct2, struct1_less> struct1_lookup;

int main()
{  
    struct1_lookup m;
    struct1 *f1 = new struct1();
    f1->x =1;
    strcpy(f1->a,"ab");
    struct2 l1;
    l1.x=10;
    m.insert(std::make_pair(f1, l1));

    struct1 fk1;
    fk1.x=1;
    struct1_lookup::iterator x = m.find(&fk1);
    if(x != m.end())
    {
        std::cout << x->first->x <<std::endl;
        std::cout << x->first->a <<std::endl;
    }

    delete f1;
    return 0;
}
0 голосов
/ 03 декабря 2018

Вы можете использовать функцию std :: find_if, например:

int search_value = 222;

auto it = std::find_if(m.begin(), m.end(), [search_value](const pair<struct1*, struct2> &s){ return s.first->x == search_value;});
0 голосов
/ 03 декабря 2018

Используйте пользовательский компаратор, чтобы передать значения, на которые вы указываете, в уже существующий operator<.Как это

struct Cmp
{
    // use pointed to value for comparison
    bool operator()(const struct1* x, const struct1* y) const { return *x < *y; }
};

std::map<struct1 *, struct2, Cmp> m;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...