迭代字符串中单词的最有效方法

use*_*039 3 c++ string loops stl

如果我想迭代字符串中的单个单词(由空格分隔),那么显而易见的解决方案是:

std::istringstream s(myString);

std::string word;
while (s >> word)
    do things
Run Code Online (Sandbox Code Playgroud)

然而,这是非常低效的.在初始化字符串流时复制整个字符串,然后将每个提取的单词一次一个地复制到word变量中(这接近于第二次复制整个字符串).有没有办法在不手动迭代每个字符的情况下对此进行改进?

das*_*ght 5

在大多数情况下,复制只占整体成本的很小一部分,因此拥有干净,高度可读的代码变得更加重要.在极少数情况下,当时间分析器告诉您复制会产生瓶颈时,您可以在标准库的帮助下迭代字符串中的字符.

您可以采用的一种方法是使用std::string::find_first_ofstd::string::find_first_not_of成员函数进行迭代,如下所示:

const std::string s = "quick \t\t brown \t fox jumps over the\nlazy dog";
const std::string ws = " \t\r\n";
std::size_t pos = 0;
while (pos != s.size()) {
    std::size_t from = s.find_first_not_of(ws, pos);
    if (from == std::string::npos) {
        break;
    }
    std::size_t to = s.find_first_of(ws, from+1);
    if (to == std::string::npos) {
        to = s.size();
    }
    // If you want an individual word, copy it with substr.
    // The code below simply prints it character-by-character:
    std::cout << "'";
    for (std::size_t i = from ; i != to ; i++) {
        std::cout << s[i];
    }
    std::cout << "'" << std::endl;
    pos = to;
}
Run Code Online (Sandbox Code Playgroud)

演示.

不幸的是,代码变得更难以阅读,所以你应该避免这种改变,或至少推迟它,直到它被要求.