Как работает счет в C ++ STL? - PullRequest
3 голосов
/ 14 ноября 2011

Итак, я пытаюсь проверить, присутствует ли конкретный объект в наборе.Для этого я использую метод count ().Теперь, похоже, не вернуть правильный ответ.Позвольте мне объяснить проблему немного яснее -

Я объявил класс таким образом

class Node{
        public:
                Node(int _state=0, int _cost=0)
                {
                        state = _state;
                        cost = _cost;
                }

                bool operator<(const Node& rhs)
                {
                        return cost < rhs.cost;
                }

                bool operator==(const Node& rhs)
                {
                        cout << "== operator method used" << endl;
                        if (rhs.state == state)
                                return true;
                        return false;
                }

                int state;
                int cost;
};

в своем коде, я объявил набор следующим образом -

set<Node*> myset;

после нескольких вставок myset выглядит следующим образом: {{1, 5}, {2, 6}, {3, 9}}

Теперь я проверяю, является ли {1, 7} частьюнабор.Как бы это сделать?Я написал метод оператора == в классе Node, который никогда не вызывается.Тогда на каком основании count () проверяет, находится ли объект уже в наборе? ... Я бы хотел, чтобы счетчик работал таким образом, что если {1, 5} уже присутствует в myset, он должен просмотреть {1,7} как повторяющаяся запись.

Ответы [ 6 ]

7 голосов
/ 14 ноября 2011

как работает счет в c ++ stl?

По умолчанию используется operator<.

На самом деле в общем случае контейнеры стандартной библиотеки C ++ используют !(a < b) && !(b < a) для определения свойства эквивалентности .

Вы можете переопределить компаратор, использованный для выполнения этой проверки, указав свой собственный аргумент шаблона Compare для типа контейнера, хотя редко бывает причиной & mdash; как правило, вместо этого вы должны просто определить operator< для своего типа, как вы уже сделали. (Однако убедитесь, что он создает строгий слабый порядок.)

в моем коде я объявляю такой набор -

set<Node*> myset;

после нескольких вставок myset выглядит следующим образом {{1, 5}, {2, 6}, {3, 9}}

Нет, ваш сет никогда не будет таким. Ваш набор содержит указателей , а не Node с. Сделайте вместо этого set<Node>.

1 голос
/ 14 ноября 2011

STL не использует оператор == для сравнения, он использует оператор < по умолчанию и этого достаточно, потому что a != b <=> a<b or b<a.Вы определили набор указателей на Node.Таким образом, ваш набор не ведет себя так, как вы хотите.Вы должны определить set<Node>.а также важно отметить, что STL использует < как для вставки, так и для поиска (т.е. функция count использует <), поэтому нельзя использовать сравнение на основе cost для вставки и сравнение на основе stateнаходка (ваш код такой!).

0 голосов
/ 14 ноября 2011

Это не работает, потому что вы объявили ser указателей , поэтому контейнер будет сравниваться.

Ваш метод сравнения < не будет использоваться, потому что std::set будет использовать стандартное сравнение между указателями. Вы также найдете дубликаты в вашем наборе, если два Node имеют одинаковое содержание, но разные адреса.

0 голосов
/ 14 ноября 2011
set<Node*> myset;

Это набор указателей; он вызывает operator== для указателей, а не для Node.

Вы должны использовать std::set<Node>, если хотите увидеть вызов Node::operator==.

0 голосов
/ 14 ноября 2011

Если вы видите, например, эту справочную страницу, вы видите, что есть параметр шаблона Compare. Вы должны реализовать свою собственную функцию сравнения.

0 голосов
/ 14 ноября 2011

Это типичный пример того, как вы бы использовали std::set, чтобы найти элемент существует или нет

#include <iostream>
#include <set>

int main(){
    std::set<int> mySet;
    mySet.insert(1);
    mySet.insert(2);
    mySet.insert(3);
    mySet.insert(4);
    mySet.insert(5);

    std::set<int>::iterator pos;
    pos = mySet.find(5);

    if ( pos == mySet.end()){
        std::cout << "Not Found" << std::endl;
    }
}

Полный пример выглядит следующим образом:

#include <iostream>
#include <set>

class Node {
public:
    Node(int _state =0, int _cost =0) : state(_state),cost(_cost) {}

    bool operator < (const Node& rhs) const {
        return cost < rhs.cost;
    }
private:
    int state;
    int cost;
};

int main(){
    std::set<Node> myset;
    myset.insert(Node(1,5));
    myset.insert(Node(2,6));
    myset.insert(Node(3,9));

    std::set<Node>::iterator pos, pos1;
    pos = myset.find(Node(1,5));
    pos1 = myset.find(Node(1,7));

    if ( pos == myset.end()){
        std::cout << "Not Found" << std::endl;
    } else {
        std::cout << "Found" << std::endl;
    }
    if ( pos1 == myset.end()){
        std::cout << "Not Found" << std::endl;
    } else {
        std::cout << "Found" << std::endl;
    }

}
...