我正在提出这个问题,因为我将我的tokenizer从strtok_r移到了C ++中的等效版本。我必须使用strtok_r代替strtok,因为我有大约2个嵌套的标记来执行。
strtok_r算法是这样的:
phpize
./configure
make
make test
make install
C ++版本是这样的(取自另一篇文章):
char *end_token, *token, *word ;
// fill 'word'
token = strtok_r (word, " ", &end_token) ;
while (token != NULL) {
// do something
token = strtok_r (NULL, " ", &end_token) ;
}
现在的问题是:为什么C ++版本对C版本如此重视? 对于长字符串,我必须使用C ++版本等待大约10秒,而C版本是瞬时使用相同的字符串。 因此,似乎C ++版本具有更高的复杂性...... 你怎么看?
答案 0 :(得分:1)
strtok()
修改字符串,用空终止符替换标记分隔符。如果你的长字符串有n个标记,那么该函数只是迭代字符串,将n个字符更改为null,这非常快。
在你的C ++替代品中,你正在制作2 * n个字符串副本,这意味着可能有2 * n个分配操作,加上(非常长的)剩余字符串的纯粹副本,这比第一个替代品重得多。不同之处在于您没有义务更改原始字符串。
您可以通过保持您未经修改的字符串保持不变来改进,例如使用偏移进行搜索:
string mystring, token ;
size_t cur_token=0, next_token ;
// fill 'mystring'
do {
next_token = mystring.find_first_of (" ", cur_token) ;
token = mystring.substr (cur_token, next_token-cur_token); // next_token-(nex_token==string::npos ? 0:cur_token) would be cleaner
if (next_token!=string::npos)
cur_token = next_token+1;
// do something with token;
} while (next_token!=string::npos);