【问题标题】:C++ Tokenizer Complexity vs strtok_rC++ Tokenizer 复杂性与 strtok_r
【发布时间】:2015-08-19 17:42:52
【问题描述】:

我提出这个问题是因为我将我的标记器从 strtok_r 移到了 C++ 中的等效版本。我必须使用 strtok_r 代替 strtok,因为我有 2 个嵌套标记化来执行大部分时间。

strtok_r 算法是这样的:

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++版本是这样的(摘自这里的另一篇文章):

string mystring, token ;
size_t next_token ;
// fill 'mystring'
while (token != mystring) {
    next_token = mystring.find_first_of (" ") ;
    token = mystring.substr (0, next_token) ;
    mystring = mystring.substr (next_token + 1) ;
    // do something
}

现在的问题是:为什么 C++ 版本如此重视 C 版本? 对于长字符串,使用 C++ 版本我必须等待大约 10 秒,而 C 版本使用相同的字符串是瞬时的。 因此,似乎 C++ 版本具有更高的复杂性...... 你怎么看?

【问题讨论】:

  • strtok 修改输入字符串,而 C++ 版本正在复制。虽然他们可能有相同的最终结果,但两个版本正在采取截然不同的路线到达终点。
  • 您可能希望了解如何拆分字符串 C++,因为它更有效:stackoverflow.com/questions/236129/split-a-string-in-c您的数据是什么样的,您想用它做什么?
  • 如果您在常量字符串上进行测试,具有等效 _builtin 的函数将始终获胜,因为它被折叠了。
  • 可能是因为 C 库是在资源稀缺且效率优于简洁设计的时代编写的,而 C++ 更关注健壮性和设计 - 但这只是我的看法 :-)

标签: c++ c tokenize strtok


【解决方案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);

Live demo

【讨论】:

  • 谢谢!我会试试。看起来很有趣!我没有发现“我的”算法必须执行如此大量的副本和分配...... :(
  • 嗨克里斯托夫,我试过你的算法。它比“我的”好得多,但仍然比 strtok 差。因为它比“我的”快 5 倍,可能比 strtok 慢 2 倍,所以无论如何我都会使用它。我可以用 2X 生存 :) 谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-11
  • 1970-01-01
  • 1970-01-01
  • 2011-03-16
  • 2011-12-17
  • 2013-04-04
  • 2021-11-17
相关资源
最近更新 更多