对大字符串进行更快的操作
Posted
技术标签:
【中文标题】对大字符串进行更快的操作【英文标题】:Faster operations on a large string 【发布时间】:2013-04-01 08:06:24 【问题描述】:假设我有一个像这样的大随机字符串......
_W:,aLH#J&A4=IY; ?RVUc?W+</59JG4WSGW6G6$QEHQ:>,*b60$BYR=D=-^8-4(0 "??YaI0Y SD9 FJ;MZ,V+'S]0:9L%;#a23cO%bMY[O6^S;ULRV2XA 8& 6_5W21E+Y$RYY$K"Q.0J+:cJC301M3H![7
L%K
Q5(4I9/9DAFR,-8<BJ=4H>9M,OX!.A4aQ:
BK<a"1ID.=U-US`R_])>GG)UL\!G?U$RRG_
HcW 3;<U5`X.?:6K@H*ZD3[M!ZU#KJXbE<Y*VV#ZYU#=]?Q
5:a^]#T
XRT.V]>57#W"U1=K$X]&JIY)::AE :K'7!_DV1B>SJ9D_`]>aC"N'US$;CaHK<N#-
"cJ,%RT)!J0DLFUb[[FOCQX(/.E3#
U
L$("+$) ;TDZ
;T#XS-'6U4`UKZ0a85D&+a]I.C/-7LDM_#/aS9OYA!#^G1II*XKL`;c
ES62Wa^=BQHK6E&A .X+4FDZ: 3UOaJ
#1<BY:;@D:`^`8E\-[9&7PXPH
... a lot more
我想对整个字符串进行操作,比如在分号后插入换行符。
#include <iostream>
#include <cmath>
#include <algorithm>
int main()
std::string buffer = "";
std::string line = "";
while (std::getline(std::cin, line))
buffer += line + std::string("\n");
auto it = std::find(buffer.begin(), buffer.end(), ';');
while (it != buffer.end())
buffer.insert(it, '\n');
it = std::find(it+1, buffer.end(), ';');
std::cout << buffer << std::endl;
return 0;
这显然需要很长时间。我该怎么办?如果我将它们分成更小的字符串会更好吗?如果没有,我怎样才能让它更快?
编辑
我是个白痴。我在这行有一个无限循环
- it = std::find(buffer.begin(), buffer.end(), ';');
+ it = std::find(it+1, buffer.end(), ';');
尽管我仍然感谢提供了很好答案的人。
【问题讨论】:
好吧,如果你想在两者之间插入东西,它不会快得多。您可以非常快速地在末尾或前面插入...其余的只是查找/搜索工作,并且文档越大需要更多时间...即使是格式良好的文件/字符串 你以后打算怎么处理这个字符串? 【参考方案1】:虽然我通常更喜欢使用 C++ 标准库,但在这种特殊情况下,我认为老式 C 风格的代码可能是更好的选择。
如果您要进行的处理取决于一次解释一个字符(例如,在分号后插入换行符),然后一次读入一个字符,然后写出一个(或两个,如果字符是如果输入和输出都被缓冲,分号并且必须后跟一个额外的换行符)将非常快。
如果字符n
的处理仅依赖于字符1
到n
,那么类似的方法将起作用——只需根据看到的字符预先决定处理操作far 或存储所有前面的字符,以便可以根据1
到n
的所有字符来决定动作。
在这两种情况下,都不需要将字符插入字符串的中间,因此必须移动大块内存。
仅当对字符 n
的处理(例如是否在该字符之后插入一个字符)取决于字符 n
之后的字符时,才需要在处理之前读入所有文本。即使这样,对于所有插入的字符必须移动的内存量也可以减少到不超过N
个字符,其中N
是已处理字符串的总长度(如果需要,还可以添加其他字符) ,通过使用如下函数:
void copyWithProcessing (char *from, char *to)
while (*from)
// do any pre-processing
*to++ = *from++;
// do any post-processing
这假设我们可以为to
指向的字符数组预先分配足够的空间,因为我们提前知道由于即将发生的处理需要多少额外的字符。或者,如果我们不需要将生成的字符串存储在内存中,我们可以在每个字符的处理完成后逐个字符地写出来,这意味着我们根本不需要为它分配任何空间。
【讨论】:
【参考方案2】:您不需要为此求助于 C 风格的编程,在 C++ 中,您可以使用 std::ostringstream
作为结果,并在您阅读的每一行中立即插入换行符:
#include <iostream>
#include <string>
#include <sstream>
int main()
std::ostringstream buffer;
std::string line;
while (std::getline(std::cin, line))
auto prev = 0;
auto pos = line.find(';');
while (pos != std::string::npos)
++pos;
buffer.write(&line[prev],pos-prev);
buffer.put('\n');
prev = pos;
pos = line.find(';',pos);
buffer.write(&line[prev],line.size()-prev);
buffer.put('\n');
std::cout << buffer.str() << std::endl;
return 0;
【讨论】:
以上是关于对大字符串进行更快的操作的主要内容,如果未能解决你的问题,请参考以下文章
QList介绍(QList比QVector更快,这是由它们在内存中的存储方式决定的。QStringList是在QList的基础上针对字符串提供额外的函数。at()操作比操作符[]更快,因为它不需要深度