繁体   English   中英

跨2个字符串的C ++搜索模式,无需串联它们

[英]C++ search pattern across 2 strings without concatenating them

我有:

std::string b;
std::string p;
const std::string sep;

b是缓冲区, p是数据包(新到达的字节), sep是分隔符序列,例如\\r\\n\\r\\n 我想在b + p找到下一个分隔符的位置,然后将p.begin(), pos范围从p移至b而又不增加b必要范围。 如果未找到sep,则附加所有内容。 逻辑上看起来像这样:

std::string cc = b + p;
auto cc_pos = std::search(cc.begin(), cc.end(), sep.begin(), sep.end());
b = std::string(cc.begin(), atcc);
if (b.size() > MAX_BYTES) 
     throw std::runtime_error("packet too large");
if (cc_pos != cc.end())
    p = std::string(cc_pos + sep.size(), cc.end());
else
    p.clear();

但是我在这里创建了临时cc ,其大小为p.size() + b.size() 如何有效地做到这一点(不分配堆内存),并且在可能的情况下优雅地做到这一点? 字符串b保留了MAX_BYTES ,因此插入速度很快,但决不能分配更多的空间。

如果我理解正确,则可以搜索b的最后n个字符,其中nsep的长度。 如果发现sep序列以b的后n个字符开头,则可以在p的开头搜索sep的第二部分。

就像是

int n = sep.size();
int remaining = n;

for (int i = 0; i < sep.size(); i++) {
    /* Search for entire sep at end of b
        if not found, search for sep minus last char
        then minus last 2 chars, 3 chars, and so on
    */
    auto it = std::search(b.end() - n - i, b.end(), sep.begin(), sep.end() - i);
    if (it != b.end()) {
        remaining = i; // number of sep chars to search for in p
        break;
    }
}

if (remaining > 0) {
    std::string sep_sub = sep.substr(n-remaining, remaining);
    std::string p_sub = p.substr(0, remaining);

    if (sep_sub == p_sub) {
        // Found sep split across b and p!
    }
}

这应该检查是否在bp发生了sep吐痰,而不必进行合并。 唯一使用的额外内存是sep_subp_sub ,它们合计的大小最多为2 * (sizeof(sep) - 1)

这仅检查sep在b和p中是否分开。 您仍然需要检查sep的整体是否不在b或p中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM