【问题标题】:c++ efficiently get substring of string with indexc ++有效地获取带有索引的字符串的子字符串
【发布时间】:2017-03-21 08:40:15
【问题描述】:

在我的项目中,我必须从 index=0 开始迭代一个大字符串并获取长度为 k 的子字符串。我已经实现了 string::substr() 并且想知道是否还有其他有效的方法。

例如:

std::string S ="ABCDEFGHIJKLMN"

我需要从 S 的开头获取长度 = 5 的所有子字符串。就像 "ABCDE""BCDEF""CDEFG"等等..

我的实现如下:

    void geekfunc(std::string &str)
{
    unsigned int index=0;
    for (; index<=(str.size()-K);++index)
    {
        ++myseqmap[str.substr(index,K)];
    }
}

这个函数被调用千万次,欢迎其他方法尝试。

【问题讨论】:

  • 我不明白您想要实现的目标:您想要输入字符串的所有长度为k 的子字符串吗?
  • 你想用这个函数解决的实际问题是什么?请花一些时间阅读 the XY problem 并思考它与您的问题有何关联。
  • 为了更清楚,我已经编辑了问题。

标签: c++ c++11 substr


【解决方案1】:

如果您使用 C++17,则可以使用 string_view 作为参数和映射键类型。这样您就不会在每次调用substr 时复制字符串内容。只需确保您传递给函数的字符串在您的地图仍在使用时不会被破坏或修改。

std::map<std::string_view, std::size_t> myseqmap;

void geekfunc(std::string_view str)
{
    unsigned int index=0;
    for (; index<=(str.size()-K);++index)
    {
        ++myseqmap[str.substr(index,K)];
    }
}

【讨论】:

    【解决方案2】:

    如果您确实需要创建子字符串的副本(string::substr 确实如此),我相信您无法通过少于Omega(m) 调用内存管理器和Omega(m * k) 复制步骤总数来解决此问题,其中m = n - k + 1 .这是因为标准要求每个字符串管理自己的内存。不允许共享(例如使用写时复制习语),因此每个子字符串都会从原始内容中复制其内容。

    如果不需要副本并且您的编译器已经提供了std::string_view,您可以尝试使用它。与string 不同,string_view 仅包含一个指向字符和大小的指针(这正是您创建子字符串的内容)。可以使用string::data获取所需的指针。

    但是,当使用string_view 时,您必须确保原始字符串在包含子字符串的容器内保持在范围内,并且在创建子字符串后它不会被更改,因为这可能会使持有的指针无效通过string_views。这些可以通过将所有内容包装在一个类中来解决,如下所示:

    struct substrings{
        const std::string original;
        container<string_view> substrings;
    };
    

    container 是您选择的任何容器。

    【讨论】:

      【解决方案3】:

      您正在为任何给定字符串搜索K-mers

      static vector<string> find_kmers(string Text, int k)
      {
          vector<string> kmers;
          int n = Text.length();;
      
          for (int i = 0; i < n-k+1; i++)
             kmers.push_back(Text.substr(i, k));               
          return kmers;
      }
      

      【讨论】:

        猜你喜欢
        • 2012-10-30
        • 2011-11-21
        • 2015-05-13
        • 2019-07-22
        • 2011-12-27
        • 1970-01-01
        • 1970-01-01
        • 2018-01-11
        • 2023-03-11
        相关资源
        最近更新 更多