Заказ звонка обратитесь к некоторой информации - PullRequest
0 голосов
/ 07 апреля 2011

теперь у меня std::map<std::string, Object> myMap.Класс Object имеет функции: int getPriority() и void Work().Сейчас я прохожу карту и хочу вызвать Work из-за приоритета объекта.

Я написал очень сумасшедшую идею: клон этой карты, но он хранит в ключе свой приоритет, например:

myMap["3_key1"] = Object();
myMap["6_key2"] = Object();
myMap["0_key3"] = Object();

Сортировка и вызов в нужной очереди: 0_key3; 3_key1; 6_key2.

Но это очень медленно, я думаю.И я хочу заменить std::map на unordered_map из boost , потому что это намного быстрее.И нет сортировки по ключу.

Итак, есть идеи?

Ответы [ 3 ]

1 голос
/ 07 апреля 2011

Если вы используете std :: set или std :: priority_queue вместо std :: map, вы можете определить функтор или просто реализовать operator <для вашего класса, чтобы std :: set упорядочивал объекты в порядке приоритета для вы. </p>

#include <iostream>
#include <set>

class Object {
  public:
    int m_priority;

    Object(int p) : m_priority(p) { }

    int getPriority() const { return m_priority; }

    void Work() const { std::cout << m_priority << std::endl; }
};

bool operator<(const Object & lhs, const Object & rhs)
{
    return lhs.getPriority() < rhs.getPriority();
}

int main()
{
    std::set<Object> container;

    container.insert(Object(1));
    container.insert(Object(9));
    container.insert(Object(5));
    container.insert(Object(8));
    container.insert(Object(3));

    for (std::set<Object>::iterator I = container.begin();
         I != container.end();
         ++I) {
        I->Work();
    }
}
1 голос
/ 07 апреля 2011

Использование Boost.MultiIndex :

// your class
#include <iostream>
#include <string>

class foo
{
public:
    foo(std::string name, unsigned priority, std::string msg) :
    mPriority(priority)
    {
        mName.swap(name); // primitive std::move :)
        mMsg.swap(msg); // (default-construct & swap)
    }

    const std::string& name() const
    {
        return mName;
    }

    unsigned priority() const
    {
        return mPriority;
    }

    void work() const
    {
        std::cout << mMsg << std::endl;
    }

private:
    std::string mName;

    unsigned mPriority;
    std::string mMsg;
};

// your container
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>

namespace bmi = boost::multi_index;

typedef boost::multi_index_container<foo,
            bmi::indexed_by<
                // order by name (std::map)
                bmi::ordered_unique<
                    bmi::const_mem_fun<foo, const std::string&, &foo::name>
                        >,

                // order by priority (std::multi_map)
                bmi:: ordered_non_unique<
                    bmi::const_mem_fun<foo, unsigned ,&foo::priority>
                        >
                > 
            > foo_set;

// test
#include <boost/foreach.hpp>

int main()
{
    foo_set fooSet;
    fooSet.insert(foo("a", 4, "this is a, priority 4"));
    fooSet.insert(foo("b", 3, "this is b, priority 3"));
    fooSet.insert(foo("c", 7, "this is c, priority 7"));
    fooSet.insert(foo("d", 1, "this is c, priority 1"));

    // view as map from name to value
    foo_set::nth_index<0>::type& nameView = fooSet.get<0>();

    nameView.find("a")->work(); // find "a", print its message
    if (nameView.find("e") == nameView.end())
        std::cerr << "e not found" << std::endl;

    std::cout << std::endl;

    // view as multi_map from priority to value
    foo_set::nth_index<1>::type& priorityView = fooSet.get<1>();

    BOOST_FOREACH(const foo& f, priorityView)
        f.work(); // work, in order of priority
}

У меня нет каких-либо тестов производительности, но это, безусловно, лучше выражает ваши намерения, и это обычно указывает на улучшение производительности в любом случае.

1 голос
/ 07 апреля 2011

Я думаю, что самый простой способ - это два контейнера.Ваша текущая карта key-> value и вторая куча ключей, упорядоченных по приоритету объекта (возможно, просто используйте priority_queue в качестве вашей реализации кучи).Это будет иметь трудности с приоритетом может измениться на лету.

...