选择具有唯一性并保持插入顺序的STL容器
在以下情况下,我无法决定使用哪个 STL 容器:
- 我想保留元素的插入顺序
- 容器中的元素必须是唯一的。
有没有现成的容器可用于此? 我不想使用向量,然后在每次执行 push_back
之前执行 std::find
。
I am unable to decide which STL container to use in the following case:
- I want to preserve the order of insertion of the elements
- The elements in the container have to be unique.
Is there any readymade container available for this? I don't want to use a vector and then perform a std::find
before doing a push_back
every time.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
Boost MultiIndex
应该能够完全满足您的要求 - 您只需使用一个排序索引即可满足“按插入顺序排序”的要求,以及hashed_unique
或ordered_unique
索引以获得唯一性要求。Boost MultiIndex
should be able to do exactly what you want - you can just use one sequenced index to get the "ordered by insertion order" requirement, and either ahashed_unique
orordered_unique
index to get the uniqueness requirement.可能有一种很好的内置方法可以做到这一点,但一种相当简单的方法是同时使用 hash_map 和列表。 每次插入之前检查 hash_map,然后插入到两者中。 您可能希望将其封装在一个类中。
There might be a good built in way to do this, but one rather simple way is to use both a hash_map and a list. Check the hash_map before each insertion, then insert into both. You'll want to encapsulate this in a class, probably.
没有标准库容器可以直接提供您想要的内容。 我将从 std::vector 开始,编写一个自由函数来执行插入操作,为您执行 find 和 push_back 操作。 如果这就足够了,就不要再继续了。 如果您遇到性能问题,请考虑更复杂的解决方案。
No standard library container gives you what you want directly. I would start with a std::vector and write a free function to do the insert which does the find and the push_back for you. If this suffices, go no further. If you have performance problems, think about a more complicated solution.
您可以这样做:
使用两个成员围绕您的元素类创建一个包装器:您的元素和索引。 我们称之为“InsertedElement”。 索引将是插入顺序。
为此类定义比较运算符,它仅考虑您的元素,但不考虑索引。 这将确保元素的唯一性,同时记住它们的插入顺序。
将 std::set 和插入计数器包装在另一个类中。 然后,当您想要插入新元素时,可以:
类似于:
You could do this:
Create a wrapper around your element class with two members: your element, and an index. Let's call it 'InsertedElement'. The index will be the insertion order.
Define comparison operator for this class, which only takes into account your element, but not the index. This will ensure the uniqueness of elements, while remembering their insertion order.
Wrap a std::set and an insertion counter in another class. Then, when you want to insert a new element, either:
Something like:
在您选择的容器(例如列表、向量、双端队列)上实现一个包装类,并重写insertion/push_back 方法以在插入元素之前检查插入的元素是否唯一。
不幸的是,我不知道任何 STL 容器符合您的标准。
Implement a wrapper class over the container you choose (e.g. list, vector, deque), and rewrite the insertion/push_back methods to check that the inserted element is unique before inserting the element.
Unfortunately,I don't know any STL container to match your criteria.
正如其他人所说,没有任何一个 STL 容器可以做到这一点。 我喜欢尼尔·巴特沃斯的回答。 另一种选择是同时使用集合和向量。 当你去插入时,检查该元素是否在集合中。 如果是,则无法插入,因为这会违反您的唯一性要求。 如果不是,请将其添加到集合中,然后将其插入向量中。 这很容易实现并且可以包装到单个类中。 代价是增加了内存开销。 但是,您可以通过在单个向量上进行查找来换取增加的计算时间。 这完全取决于您在问题域中处理的数据量以及您的时间和内存限制(如果有)。
As others have said, no single STL container can do this. I like Neil Butterworth's answer. Another option would be to use both a set and a vector. When you go to insert, check to see if the element is in the set. If it is, you can't insert as that would violate your uniqueness requirement. If it isn't, add it to the set and then insert it into the vector. This is easy to implement and can be wrapped into a single class. The tradeoff is increased memory overhead. But you trade that for increased computation time by doing the find yourself on the single vector. It all depends on how much data you are working with in your problem domain and your time and memory constraints (if any).
如果您已经安装了 boost,我喜欢这个选项。 否则,为什么不只使用列表或向量并在插入时添加检查
(find(k) == std::npos)
呢? 我想在一个非常非常大的列表上它可能会变得有点慢,但在大多数情况下它会工作得很好。If you already have boost installed, I like that option. Otherwise, why not just use a list or vector and add a check
(find(k) == std::npos)
on insertion? I suppose it could get kind of slow on a really, reallly large list, but for most cases it would work just fine.嗯,我曾经有过类似的情况。 我想到的一件事是“我可以使用多键”吗? 我用谷歌搜索了一段时间,找到了一个使用 std::set 的示例。 所以,如果你无法使用 boost(我推荐它,没有必要重新发明轮子); 你可以尝试类似下面的例子。 我认为你可以使用辅助键作为插入位置(自动增量)。 从我在互联网上找到的例子; 我根据我的需要定制了它。 这是同一版本的修改版本。
Cavaet:它使用宏。 我知道它们通常是邪恶的,但我想这种用途是可以的。
哈特哈,
Well, i once had a similar situation. One thing that came in my mind was 'can i use multi-keys'? I googled for a while, and found a sample using std::set. So, if you do not have access to boost (i recommend it, there is no point re-inventing the wheel); you can try something like the below example. I think you can use the secondary key as the position of insertion (auto-increment). From the example that i found on internet; i tailored it for my needs. This one is a modified version of the same.
Cavaet: It is using macros. I know they are evil in general, but this use is o.k. i guess.
HTH,