在C ++中分割字符串的更快捷方式

时间:2016-05-11 05:57:54

标签: c++ string substring

我有一个长度为500万的字符串来打破所需长度的子串(5或10或......)。并将片段存储到矢量中。我这样做的方式似乎需要很长时间。寻找超快的方法。

示例代码我是如何做到的。 Test here

// Example program
#include <iostream>
#include <string>
#include <vector>

int main()
{
   std::vector<std::string> splits;
   std::string text = "ABCDBCDAACBDAADCADACBBCDACDADBCAACDBCADACD";

   for(int i = 0; i < text.length() ; i+= 5)
   {
     splits.push_back(text.substr (i, 5));
     std::cout << "splits: " << text.substr(i, 5) << std::endl;

   }

}

1 个答案:

答案 0 :(得分:2)

这会快一点。

#include <iostream>
#include <string>
#include <vector>

int main()
{
   std::vector<std::string> splits;
   std::string text = "ABCDBCDAACBDAADCADACBBCDACDADBCAACDBCADACD";

   // Start timing
   splits.reserve( (text.length()+5-1)/5 );

   const auto end = text.begin() +(text.length()/5)*5;
   auto it = text.begin();
   for(; it < end; it += 5)
   {
     splits.emplace_back(it, it+5);
   }

   if (it != text.end())
   {
       splits.emplace_back(it,text.end());
   }
   //end timing

   for (const auto& str : splits)
   {
       std::cout << "splits: " << str << std::endl;
   }
}

不是使用substr创建新字符串,然后将该字符串复制到向量中,而是直接创建字符串。为了使这个尽可能简单,主循环只创建全长字符串,然后在末尾处的任何部分字符串都是单独处理的。

它还会从定时循环中删除打印(如果你真的这样做,不要!IO很慢)。

在创建字符串之前,最后在向量中保留了足够的空间(虽然我注意到你在评论中说的那样)。

说了这么多,你不使用std :: string的替代表示法,但只使用text中的偏移+长度将会更快。

鉴于你知道你只持有短字符串,一个单独的类有一个固定长度的数组(15个字节?)加上一个长度(1个字节)。可能是一个中间步骤。 glibc没有短字符串优化,所以分配2000万块内存不会那么快。

最后的想法:你已经启用了优化,没有你呢?它会产生巨大的差异。