[英]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个字符,其中n是sep
的长度。 如果发现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!
}
}
这应该检查是否在b
和p
发生了sep
吐痰,而不必进行合并。 唯一使用的额外内存是sep_sub
和p_sub
,它们合计的大小最多为2 * (sizeof(sep) - 1)
。
这仅检查sep在b和p中是否分开。 您仍然需要检查sep的整体是否不在b或p中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.