如何解决给定子字符串和索引,重新组装可能重叠的字符串片段
在不使用任何外部库的情况下,重新组合可能重叠的字符串片段(给定子字符串和索引)的一种优雅方法是什么?
例如,给定(0,“ abc”)(1,“ bcd”)(3,“ def”)(9,“ fff”)(11,“ f”) 该实现应返回“ abcdef”。
该实现还应该能够跟踪尚未汇编的字符数。在这种情况下-3,而不是4,因为(9,“ fff”)和(11,“ f”)重叠。
我正在用c ++进行编码,并使用了multimap和递归,但这似乎很慢。预先谢谢你!
解决方法
您可以一步完成。只需将所有子字符串合并为一个字符串。对未使用的空格(例如零)使用特殊字符。结果是从开始到第一个未使用的空间。从第一个未使用的空间开始,未组合的字符都是非零。
首先,将所有子字符串合并为一个字符串。它有助于预先计算总长度。此操作之后,所有未使用的空间都将存储零。
struct SubString {
size_t index;
std::string substr;
};
auto calculateTotalLength(const std::vector<SubString>& strings) {
const auto it = std::max_element(
strings.cbegin(),strings.cend(),[](const auto& a,const auto& b) {
return (a.index + a.substr.size()) < (b.index + b.substr.size());
});
return it != strings.cend() ? it->index + it->substr.size() : 0;
}
auto mergeStrings(const std::vector<SubString>& strings) {
auto result = std::string(calculateTotalLength(strings),0);
for (const auto& s : strings) {
result.replace(s.index,s.substr.size(),s.substr);
}
return result;
}
现在,您可以从第一个未使用的空格开始计算所有未组合的字符。
auto countNonAssembled(std::string_view s) {
const auto start = s.find(static_cast<char>(0));
return start != std::string_view::npos
? std::count_if(std::next(s.cbegin(),start),s.cend(),[](auto ch) { return ch != 0; })
: 0;
}
合并两个操作。
auto assemble(const std::vector<SubString>& strings) {
const auto result = mergeStrings(strings);
return std::pair{result.substr(0,result.find(static_cast<char>(0))),countNonAssembled(result)};
}
const auto [assembled,nonAssembled] =
assemble({{0,"abc"},{1,"bcd"},{3,"def"},{9,"fff"},{11,"f"}});
assert(assembled == "abcdef");
assert(nonAssembled == 3);
时间复杂度与所有子字符串的字符总数成线性关系。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。