我发现人们建议不要使用 strlen(),因为它的时间复杂度不是 O(1)。我应该在字符数组中使用什么才能知道除了
之外的时间复杂度 s[i]!='\0'
答案 0 :(得分:4)
如果你打算使用char
的C风格数组,那么我认为除了循环之外没有任何方法可以计算出长度,直到你结束。您可以自己执行此操作或致电strlen
。
但是,由于您使用c++标记了问题,因此您应该使用std::string
,然后您可以使用length
(或等效地,size
)方法而不是。
答案 1 :(得分:1)
如果您使用的是C ++,请不要使用C风格的字符串(即char*
)。请改用std::string
。 C ++标准要求std::string::size
具有O(1)复杂度。它可以通过计算字符串的长度一次并将其存储在数据成员中来实现(并在字符串长度发生变化时进行更新)。
但是,如果我们谈论的是C,那么就没有别的办法了。 C使用以null结尾的字符串。
有趣的是,某些语言(如Pascal)以不同的方式实现字符串。他们选择使用长度为前缀的字符串,而不是使用以null结尾的字符串(如C所做的那样)。这意味着每个字符串的长度都记录在开头。这有一些问题,例如,现在您需要花费额外的字节来存储长度计数器,您只能在字符串中存储有限数量的字符(例如,如果您使用2个字节作为长度,则字符串最多可能包含2 ^ 16个字符),使用子串变成了一件苦差事。
答案 2 :(得分:0)
正如评论中已经提到的那样,您可以轻松拥有一个包含长度和数据的结构,如:
struct string{
char * Data;
int Length;
}
您还可以拥有可调整大小的字符串,您也可以为其保留容量。
无论哪种方式,您都可以同时了解它的长度和库兼容性。您需要做的只是确保在创建字符串时,使其比长度大一个字节,并使最后一个字节为空。你只需要小心这种情况总会发生,否则会引起很大的问题。
答案 3 :(得分:0)
如果您使用的是char[]
,则可以使用sizeof(str) - 1
。注意std::strlen(str)
可能无论如何都会被优化。例如,将GCC 4.9.2与-O2
一起使用,代码如下:
std::cout << sizeof("hello") - 1;
std::cout << std::strlen("hello");
导致这个程序集:
[...]
movl $5, %esi
[...]
无论如何你应该使用std::string
。 std::string::size
和std::string::length
都有不变的复杂性,因为它可能像这样实现(libstdc ++):
size_type
size() const _GLIBCXX_NOEXCEPT
{ return _M_rep()->_M_length; }
正如其他人所建议的那样,您可以将长度存储在变量中并最小化对std::strlen
的调用。但总的来说,这有点像过早优化的情况。通常,C ++标准库是最好的选择。