std::multiset,跟踪元素'插入的位置

发布于 2025-01-05 07:57:02 字数 670 浏览 0 评论 0原文

我可以以某种方式重载 std::multiset 的任何运算符(就像使用 '()' 创建自定义 comapre 函数一样),以便当交换多重集中的 2 个元素时,另一个向量中的另外 2 个元素是否链接到这些元素?

我的意思是,我实际上想在多重集中插入​​ elemetns {a,b,c,d,e} ,但我也想跟踪它们在多重集中的位置,而不必使用 .find() 。所以我考虑创建另一个向量pos,其中pos[k]是元素k在多重集中的位置。

因此,如果我有这个向量 pos,当我在其中插入元素时,我仍然必须创建多重集,不仅要将其放在多重集中的正确位置,还要更改所有交换元素的 pos[]。

我不完全知道多重集如何更改/交换它的元素来对它们进行排序,但我可以以某种方式覆盖它,而不是:

swap(a,b);

我会有类似的东西。

swap(pos[a],pos[b]);
swap(a,b)

如果您对如何在不使用 .find() (对于相等元素具有 O(N) 复杂度)的情况下跟踪多重集中元素的位置有任何其他想法,那就太好了!

编辑

而且,我想我必须更改一些内容,以便当我插入新元素 (n) 时,它将在 pos[n] 之前获得正确的初始化进行任何“交换”。

Can I somehow overload any of std::multiset's operators (like you do with '()' to create a custom comapre function) so that when 2 elements in the multiset are swapped, so are another 2 elements from another vector linked to those?

I mean, I actually want to insert let's say elemetns {a,b,c,d,e} in the multiset, but I also want to keep track of their position inside the multiset, without having to use .find(). So I thought about creating another vector pos, where pos[k] is the position of element k in the multiset.

So, if I have this vector pos, I still must make the multiset when I insert an element in it, not to only put it in the right place in the multiset, but also change the pos[] of all elements swapped.

I don't exactly know how multiset changes/swaps it's element to sort them, but can I somehow override that so instead of:

swap(a,b);

I'll have something like.

swap(pos[a],pos[b]);
swap(a,b)

And if you have any other ideas of how could I keep track of an element's position inside a multiset, without using the .find() (which has O(N) complexity for equal elements) would be great!

EDIT

And also, I guess that I have to change something so that when I insert a new element (n) it will get the right initialization for pos[n] , before any "swaps" are made.

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

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

发布评论

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

评论(2

残花月 2025-01-12 07:57:03

作为替代方案,您可能需要查看顺序统计树数据结构,其具有以下功能,所有功能都在O(log n)时间内工作:

  • 插入
  • 删除
  • 查找后继
  • 查找前驱按键
  • 查找
  • 按索引查找
  • 告诉元素索引(在O(1),如果你已经有一个迭代器)

换句话说,你可以通过位置或键向树询问元素,并且可以让树告诉你给定元素所在的位置。它还按排序顺序存储元素(如 std::multiset),并且可以轻松处理重复元素。简而言之,它可以像有效支持索引的 std::multiset 一样使用。

这看起来可能是最好的方法,但不幸的是顺序统计树不在 C++ 标准库中。您需要为它们找到一个第三方库。

希望这有帮助!

As an alternative, you may want to look into the order statistic tree data structure, which has the following functionality all working in O(log n) time:

  • Insert
  • Delete
  • Find Successor
  • Find Predecessor
  • Find by key
  • Find by index
  • Tell index of element (in O(1), if you already have an iterator to it)

In other words, you can ask the tree for elements by position or by key, and can have the tree tell you what position a given element is at. It also stores the elements in sorted order (like std::multiset) and can easily be made to handle duplicate elements. In short, it can be used like a std::multiset that efficiently supports indexing.

This seems like it might be the best approach, though unfortunately order statistic trees aren't in the C++ standard library. You'd need to find a third-party library for them.

Hope this helps!

柳絮泡泡 2025-01-12 07:57:03

如果不从 multiset 继承,则无法覆盖它们,不建议这样做。因此,您需要的是跟踪多重集中元素位置的逻辑。

如果将一个元素插入到 multiset 中,您将获得该元素的迭代器。您可以使用它来确定插入的元素之前的元素,并据此确定新的位置:

std::multiset<your_item_type> it = your_set.insert(item);
std::size_t new_element_pos = it != your_set.begin() ? pos[*(it--)] + 1
                                                     : pos[*(it++)] - 1

重要的是,现在您必须更新插入的元素之后的所有项目位置,方法是将它们加一。

要跟踪交换,您可以简单地将 std::swap 专门化为您的类型,并且当交换两个元素时,您可以交换它们在位置向量中的位置。

You cannot override these without inheriting from multiset, which is not recommended. So what you need is the logic to track the positions of the elements in your multiset.

If you insert an element into the multiset, you get an iterator to that element. You can use that to determine the element before the one you inserted, and from that determine the new position:

std::multiset<your_item_type> it = your_set.insert(item);
std::size_t new_element_pos = it != your_set.begin() ? pos[*(it--)] + 1
                                                     : pos[*(it++)] - 1

The important part is that now you have to update all positions of items after the one you inserted, by increasing them by one.

To keep track of swaps, you can simply specialize std::swap for your type, and when two elements are swapped, you swap their positions in the position-vector.

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