来电订单参考一些信息

发布于 2024-10-30 08:36:59 字数 556 浏览 1 评论 0原文

现在我有 std::map; myMap. Object 类具有以下函数:int getPriority()void Work()。现在我浏览地图并由于对象的优先级而想要调用 Work

我写了一个非常疯狂的想法:该映射的克隆,但它存储在它的优先级的键中,例如:

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

它排序并调用在正确的队列中:0_key3; 3_键1; 6_key2

但我认为这非常慢。我想用 boost 中的 unordered_map 替换 std::map 因为它快得多。而且没有按键排序。

那么,有什么想法吗?

now I have std::map<std::string, Object> myMap. Class Object has funcions: int getPriority() and void Work(). Now I go through the map and want to call Work due to the priority of object.

I wrote very crazy idea: the clone of that map, but it stores in the key it's priority, for example:

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

It sorts and calling is in right queue: 0_key3; 3_key1; 6_key2.

But this is very slow, I think. And I want to replace std::map with unordered_map from boost because it's a lot faster. And there isn't sorting by key.

So, any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风情万种。 2024-11-06 08:36:59

使用 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
}

我不对它进行任何性能测试,但它肯定更好地表达了您的意图,而且这通常表明性能有所提高。

Use 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
}

I don't have any performance tests on it, but it certainly better expresses your intent, and that's usually indicative of improved performance anyway.

毅然前行 2024-11-06 08:36:59

我认为最简单的方法是两个容器。您当前的键->值映射,以及按对象优先级排序的第二个键堆(可能只使用 priority_queue 作为堆实现)。不过,这会带来困难,优先级可以动态改变。

I think the easiest way is two containers. Your current key->value map, and a second heap of keys that orders by priority of the object (possibly just use priority_queue as your heap implementation). This would have difficulties of priority can change on the fly though.

清泪尽 2024-11-06 08:36:59

如果您使用 std::set 或 std::priority_queue 而不是 std::map,您可以定义一个仿函数,或者简单地实现operator<为您的类,以便 std::set 为您按优先级顺序对对象进行排序。

#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();
    }
}

If you use std::set or std::priority_queue instead of std::map, you can define a functor, or simply implement operator< for your class so that the std::set orders the objects in priority order for you.

#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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文