在字符串中查找随机顺序子字符串

Posted

技术标签:

【中文标题】在字符串中查找随机顺序子字符串【英文标题】:Finding Randomly Order Substring in String 【发布时间】:2018-04-17 14:34:01 【问题描述】:

对于我的第一部分问题,我们已经给出了一长串输入,我们必须计算它的出现次数。 例如。

Input = AXBHAAGHXAXBH
Find = AXBH
Output = 2

这可以通过使用string.find("term") 循环来实现。例如。

#include <string>
#include <iostream>
int main()

   int occurrences = 0;
   std::string::size_type pos = 0;
   std::string inputz = "AXBHAAGHXAXBH";
   std::string target = "AXBH";
   while ((pos = inputz.find(target, pos )) != std::string::npos) 
          ++ occurrences;
          pos += target.length();
   
   std::cout << occurrences << std::endl;


但是,我不确定第二部分在哪里做,它需要考虑随机结构: 随机结构是指我们发现的任何方向。重要说明:查找事件总是组合在一起,但可以具有不同的结构。 我不想用例,因为某些样本发现太大了,例如。查找 AXBHNMB 需要考虑的案例太多,并希望采用更通用的方法。

Eg. AXBH is find, then AXHB is also acceptable for the occurence

一个恰当的例子:

Input = AXBHAAGHXAXBH**ABHX**NBMN**AHBX**
Find = AXBH
Output = 4

如果您请为给定的示例编写代码,并附上您使用的任何新功能的解释/说明链接。

【问题讨论】:

你是在问如何找到一个字符串中的所有子串排列? inputfind 是否只包含大写字母? @Ron 将子串组排列在一起。我已经更新了问题,例如。如果 find 是 AXB 则输入将始终将它们组合在一起,例如。 AXBNMNNOBXANBMOAXB @arsho 是的。输入总是大写 @Gengestu 感谢您的编辑 【参考方案1】:

您是正确的,检查所有排列将花费大量时间。幸运的是,我们不需要这样做。我们可以做的是将要查找的字符串存储在std::map&lt;char, int&gt;/std::unordered_map&lt;char, int&gt; 中,然后从字符串中获取子字符串进行搜索,将它们转换为相同类型的映射,看看这些映射是否相等。这让我们可以在不关心顺序的情况下使用比较,它只是确保我们拥有正确数量的每个字符。所以我们会有类似的东西

int main()

    std::string source = "AHAZHBCHZCAHAHZEHHAAZHBZBZHHAAZAAHHZBAAAAHHHHZZBEWWAAHHZ ";
    std::string string_to_find = "AAHHZ";
    int counter = 0;

    // build map of the characters to find
    std::unordered_map<char, int> to_find;
    for (auto e : string_to_find)
        ++to_find[e];

    // loop through the string, grabbing string_to_find chunks and comparing
    for (std::size_t i = 0; i < source.size() - string_to_find.size();)
    
        std::unordered_map<char, int> part;
        for (std::size_t j = i; j < string_to_find.size() + i; ++j)
            ++part[source[j]];

        if (to_find == part)
        
            ++counter;
            i += string_to_find.size();
        
        else
        
            ++i;
        
    

    std::cout << counter;

【讨论】:

非常感谢 :) 我理解你的大部分方法。你能解释一下“建立要找到的角色的地图”吗? @Slava AFAIK 这是 O(NM) 其中 N 和 M 是每个字符串的大小。 我认为添加条件if( part[c] &gt; to_find[c] ) break;可以显着优化它 @UtsoRoy for (auto e : string_to_find) 循环遍历string_to_find 中的每个字符。 ++to_find[e] 表示将该字符存储在映射中并增加该字符映射到的 int 的值。当你说++to_find['a'] 如果'a' 不在地图中,那么它会将它放在地图中并给它一个值1。如果'a' 已经在地图中,那么它只会增加值。 @Slava 也许。我必须对其进行分析,看看分支机构的成本是否值得。【参考方案2】:

一种简单的方法是遍历给定的字符串并搜索目标字符串。

在每个块中,我们需要对部分进行排序并比较它是否与目标字符串匹配。

#include <string>
#include <iostream>
#include <algorithm>

int main()

    int occurrences = 0;
    std::string::size_type pos = 0;
    std::string inputz = "AXBHAAGHXAXBH**ABHX**NBMN**AHBX**";
    std::string target = "AXBH";
    std::sort(target.begin(), target.end());
    int inputz_length = inputz.length();
    int target_length = target.length();
    int i=0;
    for(i=0; i<=inputz_length-target_length; i++)
    
        std::string sub = inputz.substr(i, target_length);
        std::sort(sub.begin(), sub.end());
        if (target.compare(sub) == 0)
        
            std::cout << i<<"-->"<< target<<"-->" << sub << std::endl;
            occurrences++;
            i=i+target_length;
        
    
    std::cout << occurrences << std::endl;
    return 0;

输出:

0-->ABHX-->ABHX
9-->ABHX-->ABHX
15-->ABHX-->ABHX
27-->ABHX-->ABHX
4

额外函数:使用algorithm头文件中的sort函数。

时间复杂度:大于 O(n2)

【讨论】:

如果你喜欢它,放弃投票并接受它作为答案:)【参考方案3】:

一种解决方案是找到搜索字符串和子字符串的规范表示。有两种快速方法是可能的。

1) 对子字符串进行排序。 2) 计算字母的直方图。

选项 2 可以通过在搜索窗口中增加传入字母的直方图 bin 并减少传出字母的 bin 来递增计算。

在更新直方图箱时,还可以检查此特定更新是否会切换整体匹配:

// before adding the incoming letter
if (h[incoming] == target[incoming]) matches--;
else if (++h[incoming] == target[incoming]) matches++;
// before subtracting outgoing letter
if (h[outgoing] == target[outgoing]) matches--;
else if (--h[outgoing] == target[outgoing]) matches++; 

if (matches == number_of_unique_letters) occurences++;

那么整体复杂度就变成了O(n)。

【讨论】:

以上是关于在字符串中查找随机顺序子字符串的主要内容,如果未能解决你的问题,请参考以下文章

PB中取字符串子串的函数是啥

数组篇在python中如何查找最长字符串子串

字符串子串的查找

C++编程,查找字符串子串并替换。

[在python中使用正则表达式搜索字符串子字符串

如何更改python字符串子字符串信息