微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

给定子字符串和索引,重新组装可能重叠的字符串片段

如何解决给定子字符串和索引,重新组装可能重叠的字符串片段

在不使用任何外部库的情况下,重新组合可能重叠的字符串片段(给定子字符串和索引)的一种优雅方法是什么?

例如,给定(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 举报,一经查实,本站将立刻删除。