跨越2个字符串的C ++搜索模式,没有连接它们

时间:2018-03-30 06:49:42

标签: c++ stl

我有:

b

p是缓冲区,sep是数据包(新到达的字节),\r\n\r\n是分隔符序列,例如b + p。我想在p.begin(), pos中找到下一个分隔符的位置,然后将范围pb移到b,而不会增加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(); 。如果找不到sep,只需附加一切。从逻辑上看,它看起来像这样:

cc

但是我在这里创建了大小为p.size() + b.size()的临时b。如何有效地完成(不分配堆内存),如果可能的话,优雅?字符串MAX_BYTES保留O(nr*np),因此插入速度很快,但它永远不会分配更多。

1 个答案:

答案 0 :(得分:1)

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

这样的东西
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!
    }
}

这应该检查sep bp之间是否发生sep_sub吐,而不必连接。唯一使用的额外内存是p_sub2 * (sizeof(sep) - 1),其组合最多为i

这只检查sep是否在b和p之间分割。你仍然需要检查整个sep是否在b或p中。