1

假设我有一个像这样的大随机字符串......

_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(), ';');

尽管我仍然赞扬提供了一个很好答案的人。

4

2 回答 2

1

虽然我通常更喜欢使用 C++ 标准库,但在这种特殊情况下,我认为老式的 C 风格代码可能是更好的选择。

如果您要进行的处理仅取决于一次解释一个字符(例如,在分号后插入换行符),然后一次读入一个字符,然后写出一个(或两个,如果字符是分号和必须跟一个额外的换行符)如果输入和输出都被缓冲,将会非常快。

如果字符的处理n只依赖于字符1to n,那么类似的方法会起作用——只需要根据目前看到的字符预先决定处理动作,或者存储所有前面的字符,以便动作可以根据所有字符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因为我们事先知道由于即将发生的处理需要多少额外的字符。或者,如果我们不需要将生成的字符串存储在内存中,我们可以在每个字符的处理完成后逐个字符地写出来,这意味着我们根本不需要为它分配任何空间。

于 2013-04-01T08:53:18.933 回答
1

您不需要为此求助于 C 风格的编程,在 C++ 中,您可以使用 astd::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;
 }
于 2013-04-01T09:02:54.790 回答