std::string pop_back()
:删除字符串的最后一个元素
在C ++规范中,据说C ++ 11字符串类函数pop_back具有恒定的时间复杂度。
(更确切地说 - 未指定但通常不变)
http://www.cplusplus.com/reference/string/string/pop_back/
除此之外,我阅读了C ++ 11规范的草案,据说pop_back
等于str.erase(str.length() -1)
。据我所知,擦除功能只需分配一个新的内存量,并将剩余的元素(未删除)复制到此内存中,这将占用线性时间。鉴于此,pop_back如何在恒定时间内完成。
答案 0 :(得分:9)
不必重新分配。
该函数可能只是用零覆盖最后一个字符并减少一些长度信息。
答案 1 :(得分:-1)
关于"复杂性"你总是要看大局,而不仅仅是个案。
让我们先看看push_back()
的增长情况。如果从一个空容器增长到一个大容量N的容器,实现将进行一些重新分配。每次它的复杂度将是O(M)
当前的大小,但其余的迭代将是恒定的时间。
实际上,复杂性将是几何级数的总和。让我们说它重新分配到容量加倍的容量,让我们说它从16开始。
因此,重新分配的人的复杂性将是:
16 + 32 + 64 + 128 + ... + N/2
(假设N是2的幂),如您所知,将总和为
N-16.
为没有重新分配的单个内容添加所有内容,并且您的总和接近2N
,因此对于所有O(N)
插入都是N
,并且因此,在大图中每次插入的时间不变,即使这个特定的可能不是。
现在就是这样的例子。我们假设我们从N
开始并执行大量pop_back()
次调用。假设反向完全相同,它将具有相同的复杂性。
Q.E.D。
当然这里还有更多问题。例如,pop_back
和erase
可能不会抛出,即泄漏异常,甚至重新分配到较小的缓冲区将首先需要分配更多的内存来移动数据,然后再释放旧的,所以这样做可能会发生异常。然而,实施可以简单地尝试"尝试"重新分配到一个较小的缓冲区,如果发生错误,抓住它然后恢复到一个简单的逻辑"更改。当然,这确实意味着您的系统已达到最大容量,并且减少字符串的大小并没有帮助。
可能性是,虽然这对实现是开放的,但大多数实现永远不会在pop_back中重新分配。这样的事情唯一可能发生的事情是,如果字符串是用小字符串的内部成员缓冲区实现的,并且达到了这个长度,在这种情况下,将所有数据移入其中并释放"空闲存储"记忆。那不能扔。