deque::insert() 在索引处?

发布于 2024-12-11 09:19:06 字数 122 浏览 0 评论 0原文

如何在线性时间内 insert() 将一堆项目插入到 deque 的中间?

(我插入的项目无法通过 STL 样式迭代器访问。)

How do I insert() a bunch of items to the middle of a deque in linear time?

(The items I am inserting are not accessible through an STL-style iterator.)

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

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

发布评论

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

评论(4

·深蓝 2024-12-18 09:19:06

有一个 deque::insert(iterator pos, const T&x) 函数,将位置 pos 作为 deque::iterator 和一个单一的元素。使用这种方法,您可以一一插入所有元素。 pos 可以通过 deque.begin()+index 轻松获得(如果您有一个要在其之前插入元素的索引)。 insert 方法为新插入的元素返回一个迭代器,只需增加此返回的迭代器即可获取下一个位置:

deque::iterator it = myDeque.begin()+index;
while(n--) {
  it = myDeque.insert(it, currentElement);
  it++;
  currentElement = ... // However you get your next element ...
}

但是,这可能需要 O(n*k) 时间,因为插入单个元素的 (iirc) 是线性时间运算 iirc。

第二个重载是 deque::insert(iterator pos, InputIterator f, InputIterator l):请记住,简单指针也满足 STL 输入迭代器的要求,因此如果您有一个 C 样式数组 < code>T array[] 长度为 n 包含您的元素,您可以插入此数组中的所有元素

d.insert(pos, array, array+n);

此操作可以在线性时间内执行,即 O(n +k)。我不确定标准是否保证这一点,但我认为大多数实现都会有效地做到这一点。

编辑

我快速检查了微软的实现,他们通过push_backpush_front序列来实现,无论什么更接​​近pos< /code> 然后将元素旋转到最终位置,这保证了上述 O(n+k) 复杂度。当然,这也可以“手动”完成,例如:(

size_type _Off = pos - d.begin();
size_type _Oldsize = d.size();
if (_Off <= d.size() / 2)
{   // closer to front, push to front then rotate
  while (hasMoreElements())
    push_front(nextElement()); // prepend flipped

  size_type _Num = d.size() - _Oldsize;
  std::reverse(d.begin(), d.begin() + _Num); // flip new stuff in place
  std::rotate(d.begin(), d.begin() + _Num, begin() + _Num + _Off);
}
else
{ // closer to back
  while (hasMoreElements())
    push_front(nextElement()); // prepend flipped

  std::rotate(begin() + _Off, begin() + _Oldsize, end());
}

我从 Microsoft 的 deque::insert 实现中复制了代码,删除了调试代码和异常处理,

There is a deque::insert(iterator pos, const T&x) function taking the position pos as deque::iterator and a single element. Using this method you could insert all elements one by one. pos can easily be obtained (if you have an index before which you want to insert the element) by deque.begin()+index. The insert method returns an iterator for the newly inserted element, simply increment this returned iterator to get the next position:

deque::iterator it = myDeque.begin()+index;
while(n--) {
  it = myDeque.insert(it, currentElement);
  it++;
  currentElement = ... // However you get your next element ...
}

This however cantake O(n*k) time, since insertion of a single element is (iirc) a linear time operation iirc.

The second overload is deque::insert(iterator pos, InputIterator f, InputIterator l): Remember that simple pointers also fulfill the requirements of an STL input iterator, so if you have a C-Style array T array[] of length n containing your elements, you could insert all elements from this array with

d.insert(pos, array, array+n);

This operation can be carried out in linear time, i.e. O(n+k). I'm not sure if this is guaranteed by the standard, but I suppose that most implementation will do it efficiently.

EDIT

I quickly checked with Microsoft's implementation, they do it by a sequence of either push_back or push_front, whatever is closer to pos and then rotating the elements to their final place, which guarantees the above O(n+k) complexity. Of course, that could also be done "by hand" like:

size_type _Off = pos - d.begin();
size_type _Oldsize = d.size();
if (_Off <= d.size() / 2)
{   // closer to front, push to front then rotate
  while (hasMoreElements())
    push_front(nextElement()); // prepend flipped

  size_type _Num = d.size() - _Oldsize;
  std::reverse(d.begin(), d.begin() + _Num); // flip new stuff in place
  std::rotate(d.begin(), d.begin() + _Num, begin() + _Num + _Off);
}
else
{ // closer to back
  while (hasMoreElements())
    push_front(nextElement()); // prepend flipped

  std::rotate(begin() + _Off, begin() + _Oldsize, end());
}

(I copied the code from Microsofts implementation of deque::insert, removing debug code and exception handling,

吃不饱 2024-12-18 09:19:06

调用需要插入一系列项目的插入方法,请参阅此处列出的第三种方法:

http://msdn.microsoft.com/en-us/library/zcww84w5(v=vs.71).aspx

并且,创建您自己的 STL 样式迭代器来访问您想要插入的项目。请参阅:

C++ 中的自定义迭代器

Call the insert method that takes a sequence of items to insert, see the 3rd method listed here:

http://msdn.microsoft.com/en-us/library/zcww84w5(v=vs.71).aspx

And, create your own STL-style iterator to access the items you want to insert. See:

Custom Iterator in C++

闻呓 2024-12-18 09:19:06

输入:

双端队列:lengtl = l,

新项目(m = 新项目的数量)

算法:

创建一个新的双端队列 (1)

复制原始双端队列中的所有项目,直到您所在的位置想要插入新的 (p)

添加新的项目 (m)

从旧的双端队列中添加项目 (mp)

也许您可以只使用新的双端队列,但最坏的情况是:

将新的双端队列复制到旧的双端队列上(完全清除后:):

成本(l+m)

最坏的成本是因此: origsize * 2 + newitems 是线性的。

这里不计算“干净的牌组”,但它也是线性的(最坏的情况下)。

Input:

Deque: lengtl = l,

New items (m = number of new items)

Algo:

create a new deque (1)

Copy all items from original deque until where you want to insert the new ones (p)

Add new items (m)

Add items from old deque (m-p)

Maybe you can just use the new deque but at worst:

Copy new deque onto old one (after a complete clear: ):

Cost (l+m)

The worst cost is thus: origsize * 2 + newitems which is linear.

The "clear deck" isn't counted here but it is also linear ( at worst).

给我一枪 2024-12-18 09:19:06

将插入点之后的所有元素添加到向量中。
删除插入点之后的所有元素。
将新范围附加到双端队列。
将向量附加到双端队列。

这是 O(2n) 最坏情况,而不是 O(n^2)。

Add all the elements after the insertion point to a vector.
Remove all elements after insertion point.
Append new range to deque.
Append vector to deque.

This is O(2n) worst case, instead of O(n^2).

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