简体   繁体   English

我应该使用哪个容器

[英]which container should i use for this

Let's say I want to have a container of Apples that have different prices. 假设我想拥有一个价格不同的苹果容器。 I want them sorted by their price always (highest price first), but I also want to quickly retrieve them by their id. 我希望它们按价格排序(最高价格优先),但我也希望通过他们的ID快速检索它们。 What I have so far is the following 到目前为止我所拥有的是以下内容

struct AppleClass
{
    string id;
    int price;

    bool operator<(const AppleClass& o) const 
    {
        return price > o.price; 
    }
};

int main() 
{
    set<AppleClass> myapples;
    myapples.insert({"apple1", 500});
    myapples.insert({"apple2", 600});
    myapples.insert({"apple3", 400});

    for (auto& apple : myapples)
    {
        cout << apple.id << "," << apple.price << endl;         
    }
}

http://ideone.com/NcjWDZ http://ideone.com/NcjWDZ

My app will spend 20% of it's time removing entries, 20% inserting entries, 25% retrieving them (retrieving the whole list), and 35% updating them (their price will increase or decrease) often. 我的应用程序将花费20%的时间删除条目,20%插入条目,25%检索它们(检索整个列表),35%更新它们(它们的价格将增加或减少)经常。

The container will have a maximum of 450 entries. 容器最多可包含450个条目。

My code only solves the sort problem. 我的代码只解决了排序问题。 Find is useless since I want to find by their id (so I need to iterate trough all of them). 查找是无用的,因为我想通过他们的id找到(所以我需要迭代所有这些)。 Removing and inserting would be slow for the same reason. 出于同样的原因,删除和插入会很慢。

It feels like the wrong choice. 这感觉是错误的选择。

But If I have a map then it would be ordered based on the id. 但是,如果我有一张地图,那么它将根据id进行排序。 And every time I retrieve the list I would have to copy it to some container for example, order it, and then send it to the user, which also feels slow. 每次我检索列表时,我都必须将其复制到某个容器中,例如,订购它,然后将其发送给用户,这也感觉很慢。

Help! 救命!

You can do it with two containers, one that's kept sorted by price (priority queue or linked list), and one that indexes your ids (a hash map). 您可以使用两个容器,一个按价格(优先级队列或链接列表)排序,另一个索引您的ID(哈希映射)。 In order to save space, you can have both structures keep only pointers to your Apple instances, you'll need to write a custom sort functor for that though. 为了节省空间,您可以让两个结构只保留指向Apple实例的指针,但是您需要为此编写自定义排序函数。

This way, your entry removal is O(1) , insertion is O(log n) , retrieval is also O(1) , and updating is O(log n) . 这样,您的条目删除是O(1) ,插入是O(log n) ,检索也是O(1) ,更新是O(log n) I think that should be good, especially when you're dealing with such a small number of items (450). 我认为这应该是好的,特别是当你处理这么少的物品时(450)。

EDIT: 编辑:

Elaborating on operation costs: 详细说明运营成本:

All these operations are constant time for the hash map, so this is about the priority queue: 所有这些操作都是哈希映射的常量时间,因此这是优先级队列:

  • Removal : you can get an amortized cost of O(1) with the priority queue if you defer that cost to inserts. 删除 :如果将该成本推迟到插入,则可以使用优先级队列获得O(1)的摊销成本。 There are lots of clever implementations out there that will show you how to do this. 有很多聪明的实现会告诉你如何做到这一点。
  • Insertion : Any basic priority queue implementation will do this in O(log n) , it gets a little tricky to keep it that way if you want constant time removal. 插入 :任何基本的优先级队列实现都会在O(log n)执行此操作,如果您希望不断删除时间,那么保持这种方式会有点棘手。
  • Retrieval : You use the map for this, no need to look through the priority queue. 检索 :您可以使用映射,无需查看优先级队列。
  • Updating : I don't think there's a (easy) way to get better complexity than O(log n) for updating, even amortized, you'll probably have to shuffle things around in the priority queue for the average case. 更新 :我认为有一种(简单的)方法可以获得比O(log n)更好的复杂性来进行更新,甚至是分期付款,你可能不得不在优先级队列中为普通情况改变现状。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM