C++ std::string size()是一个O(1)操作吗?
std::string size()是一个O(1)操作吗 我使用的STL的实现是内置在VC中的++C++ std::string size()是一个O(1)操作吗?,c++,visual-c++,stl,stdstring,C++,Visual C++,Stl,Stdstring,std::string size()是一个O(1)操作吗 我使用的STL的实现是内置在VC中的++ size_type __CLR_OR_THIS_CALL size() const { // return length of sequence return (_Mysize); } 因此,最终可能是这样,但您永远无法确定。是的,std::string::size()是O(1)。对于容器,STL保证性能至少是O(N),但是包括std::string在内的许多容器都可以作为O(
size_type __CLR_OR_THIS_CALL size() const
{ // return length of sequence
return (_Mysize);
}
因此,最终可能是这样,但您永远无法确定。是的,std::string::size()是O(1)。对于容器,STL保证性能至少是O(N),但是包括std::string在内的许多容器都可以作为O(1)实现,并且将实现。通常,它要么返回一个简单变量,要么执行类似于“结束-”的操作并返回该变量。参见本标准第23.1节中的表65。“a.size()”列为“(注a)”,表示“这些条目……应具有恒定的复杂性”
第21.3节说字符串符合序列(23.1)的要求,事实上,size()是常数时间。如果你问MSVC对string::size()的实现是否具有常数复杂性,那么答案是肯定的。但是在C++标准的23.1中提到表65,它表示<代码> siz()/Cuth>的复杂性应该遵循“注释A”中所说的。注A说: 标记为“”的条目(注A)' 应该具有恒定的复杂性 然而,这并不意味着这些条目具有恒定的复杂性。标准使用非常具体的术语,“应该”意味着它不是强制性的 “注A”被添加到标准中,专门用来安抚那些认为
size()
应具有线性复杂性的人,这样在修改容器时就没有必要保留尺寸
因此,您不能依赖于具有恒定复杂性的
size()
,但老实说,我不确定是否有任何实现没有恒定的string::size()
对于msvc++,这里有一个简单的方法来回答这个问题
在项目中编写一些代码:
string happy;
happy.size();
Hilight.size调用,右键单击,转到定义
在我的安装(vs2005sp1)中,这会将我发送到xstring:1635,如下所示:
size_type __CLR_OR_THIS_CALL size() const
{ // return length of sequence
return (_Mysize);
}
因此,字符串似乎有一个名为_Mysize的成员,它只是返回该成员
换句话说,这是一个O(1)实现。对于字符串,对于所有不使用rope(1)的字符串实现,
size()
操作必须是常量。标准中没有明确要求操作为O(1)
,最接近的是一般要求size()
应为常数时间,但这为任何其他复杂性度量留下了空间
那么为什么一定是O(1)
这是因为无法根据字符串本身的内容计算大小。在C中,使用NUL终结符来确定字符串的结尾,在C++中,NUL与字符串中的任何其他字符一样有效。由于无法根据内容(2)计算字符串的大小,因此必须从外部处理它,与字符串的实际大小无关
(1) C++03标准允许一个实现使用rope作为字符串的实现,但事实是,目前的标准库实现都没有使用rope
(2) 如果实现使用了rope,那么如果通过链表或类似结构链接块,或者如果允许块具有不同的大小,则操作可以通过构建rope的块的数量来取决于大小。但据我所知,rope在任何标准库实现中都没有使用。size()的复杂性应该遵循“Note A”。这意味着,它应该具有恒定的复杂性,即O(1)。虽然,我不确定实现,但是C++中的迭代器确实有关联的操作,如Sun()和Enter(),指向STL容器。这些操作具有恒定的时间复杂性,因为它们是容器需求。这意味着
begin()-end()
也具有恒定的复杂性。这意味着,size()
是一个O(1)操作。我想你被否决了,因为你没有回答问题,你要求读者把点连接起来。而且你的答案也很神秘,我看不出有任何改变。对我来说,答案仍然很神秘。“…它最终可能是”这样“?这段代码不是从实际实现中提取的吗?顺便说一句,仍然可以通过标准方式以O(1)操作检索字符串的大小:(end()-begin())
。这保证是[摊销]O(1),因为begin()
和end()
都必须是O(1)(容器要求),字符串迭代器是随机访问的(字符串要求),对于支持它的迭代器(迭代器要求)operator-
必须是O(1)。。。。而且字符串的长度不能从内容中计算出来,因为可以存储的值没有限制。这意味着它必须在内容的外部进行管理,因此独立于N,即它必须是O(1)。并非所有容器都需要O(1)
这一事实并不意味着它可以O(N)
在容器中,只是至少可以有一个容器是非常量的,例如std::list
@DavidRodríguez dribeas:Hmmm,可以使用“编码”避免在任何地方显式存储长度。例如,使用0字节作为转义字符,其含义取决于以下字节:0表示“字符串结束”,非零表示“有那么多0字节”。可能是其他<代码> STD::String 它指的是容器需求(即推荐的常数大小),在11 s中