📜  字谜子串搜索(或搜索所有排列)|设置 2

📅  最后修改于: 2022-05-13 01:56:15.576000             🧑  作者: Mango

字谜子串搜索(或搜索所有排列)|设置 2

给定一个文本txt[0..n-1]和一个模式pat[0..m-1] ,编写一个函数search(char pat[], char txt[]) 打印所有出现的pat[]及其txt[]中的排列(或字谜)。您可以假设n > m

例子:

方法:目前的方法是基于滑动窗口和哈希表。

  • 创建一个哈希表来存储模式中所有字符的哈希
  • 创建一个哈希表以存储窗口 m 的文本中所有字符的哈希值
  • 遍历窗口 m 中的字符串文本并比较哈希表。
  • 如果发现相同,则将子字符串的索引作为答案之一。

下面是上述方法的实现:

C++
// C++ program to search all anagrams
// of a pattern in a text
 
#include 
#define MAX 256
using namespace std;
 
// Function to find all anagrams using hashtable
vector findAnagrams(string s, string p)
{
    int n = s.length(), m = p.length();
 
    // Vector to store all indices of substrings
    // that are anagram of string p
 
    vector ans;
 
    // Handling edge cases
    if (n < m || m == 0)
        return ans;
 
    // Hashtables for both strings
    vector ms(26, 0), mp(26, 0);
 
    // Initialise the hashtable for string p
    for (char c : p) {
        mp++;
    }
 
    int i = 0;
    bool flag = true;
 
    // Initialise the hashtable
    // for string s for window m
    for (i = 0; i < m; i++) {
        ms[s[i] - 'A']++;
    }
 
    // Check if current hashtables are same
    // for current window m
 
    for (int j = 0; j < 26; j++)
        if (mp[j] != ms[j])
            flag = false;
 
    // if same, push the index of
    // Starting substring into window m
 
    if (flag)
        ans.push_back(0);
 
    // Traverse string s with window m
    for (i = m; i < n; i++) {
        ms[s[i - m] - 'A']--;
        ms[s[i] - 'A']++;
 
        // Check if current hashtables are same
        // for current window m
        if (mp[s[i] - 'A'] == ms[s[i] - 'A']
            && mp[s[i - m] - 'A'] == ms[s[i - m] - 'A']) {
            flag = true;
            for (int j = 0; j < 26; j++)
                if (mp[j] != ms[j])
                    flag = false;
        }
        else
            flag = false;
 
        // if same, push the index
        // of starting substring
        // into answer
        if (flag)
            ans.push_back(i - m + 1);
    }
 
    // Return the final vector of indices
    return ans;
}
 
// Driver program
int main()
{
    char txt[] = "BACDGABCDA";
    char pat[] = "ABCD";
    vector indices = findAnagrams(txt, pat);
    cout << "[ ";
    for (auto i : indices)
        cout << i << " ";
    cout << "]";
    return 0;
}


Java
// Java program to search all anagrams
// of a pattern in a text
import java.util.*;
 
class GFG
{
  static final int MAX = 256;
 
  // Function to find all anagrams using hashtable
  static Vector findAnagrams(String s, String p)
  {
    int n = s.length(), m = p.length();
 
    // Vector to store all indices of subStrings
    // that are anagram of String p
 
    Vector ans = new Vector();
 
    // Handling edge cases
    if (n < m || m == 0)
      return ans;
 
    // Hashtables for both Strings
    int [] ms = new int[26];
    int [] mp = new int[26];
 
    // Initialise the hashtable for String p
    for (char c : p.toCharArray()) {
      mp++;
    }
 
    int i = 0;
    boolean flag = true;
 
    // Initialise the hashtable
    // for String s for window m
    for (i = 0; i < m; i++) {
      ms[s.charAt(i) - 'A']++;
    }
 
    // Check if current hashtables are same
    // for current window m
 
    for (int j = 0; j < 26; j++)
      if (mp[j] != ms[j])
        flag = false;
 
    // if same, push the index of
    // Starting subString into window m
 
    if (flag)
      ans.add(0);
 
    // Traverse String s with window m
    for (i = m; i < n; i++) {
      ms[s.charAt(i-m) - 'A']--;
      ms[s.charAt(i) - 'A']++;
 
      // Check if current hashtables are same
      // for current window m
      if (mp[s.charAt(i) - 'A'] == ms[s.charAt(i) - 'A']
          && mp[s.charAt(i-m) - 'A'] == ms[s.charAt(i-m) - 'A']) {
        flag = true;
        for (int j = 0; j < 26; j++)
          if (mp[j] != ms[j])
            flag = false;
      }
      else
        flag = false;
 
      // if same, push the index
      // of starting subString
      // into answer
      if (flag)
        ans.add(i - m + 1);
    }
 
    // Return the final vector of indices
    return ans;
  }
 
  // Driver program
  public static void main(String[] args)
  {
    String txt = "BACDGABCDA";
    String pat = "ABCD";
    Vector indices = findAnagrams(txt, pat);
    System.out.print("[ ");
    for (int i : indices)
      System.out.print(i+ " ");
    System.out.print("]");
  }
}
 
// This code is contributed by shikhasingrajput


Python3
# python3 program to search all anagrams
# of a pattern in a text
MAX = 256
 
# Function to find all anagrams using hashtable
def findAnagrams(s, p):
 
    n, m = len(s), len(p)
 
    # Vector to store all indices of substrings
    # that are anagram of string p
 
    ans = []
 
    # Handling edge cases
    if (n < m or m == 0):
        return ans
 
    # Hashtables for both strings
    ms, mp = [0 for _ in range(26)], [0 for _ in range(26)]
 
    # Initialise the hashtable for string p
    for c in p:
        mp[ord(c) - ord('A')] += 1
 
    i = 0
    flag = True
 
    # Initialise the hashtable
    # for string s for window m
    for i in range(0, m):
        ms[ord(s[i]) - ord('A')] += 1
 
    # Check if current hashtables are same
    # for current window m
 
    for j in range(0, 26):
        if (mp[j] != ms[j]):
            flag = False
 
    # if same, push the index of
    # Starting substring into window m
 
    if (flag):
        ans.append(0)
 
    # Traverse string s with window m
    for i in range(m, n):
        ms[ord(s[i - m]) - ord('A')] -= 1
        ms[ord(s[i]) - ord('A')] += 1
 
        # Check if current hashtables are same
        # for current window m
        if (mp[ord(s[i]) - ord('A')] == ms[ord(s[i]) - ord('A')]
                and mp[ord(s[i - m]) - ord('A')] == ms[ord(s[i - m]) - ord('A')]):
            flag = True
            for j in range(0, 26):
                if (mp[j] != ms[j]):
                    flag = False
 
        else:
            flag = False
 
        # if same, push the index
        # of starting substring
        # into answer
        if (flag):
            ans.append(i - m + 1)
 
    # Return the final vector of indices
    return ans
 
# Driver program
if __name__ == "__main__":
 
    txt = "BACDGABCDA"
    pat = "ABCD"
    indices = findAnagrams(txt, pat)
    print("[ ", end="")
    for i in indices:
        print(i, end=" ")
    print("]")
 
# This code is contributed by rakeshsahni


C#
// C# program to search all anagrams
// of a pattern in a text
using System;
using System.Collections;
 
class GFG {
 
    static int MAX = 256;
 
    // Function to find all anagrams using hashtable
    static ArrayList findAnagrams(string s, string p)
    {
        int n = s.Length, m = p.Length;
 
        // Vector to store all indices of subStrings
        // that are anagram of String p
 
        ArrayList ans = new ArrayList();
 
        // Handling edge cases
        if (n < m || m == 0)
            return ans;
 
        // Hashtables for both Strings
        int[] ms = new int[26];
        int[] mp = new int[26];
 
        // Initialise the hashtable for String p
        foreach(char c in p.ToCharArray())
        {
            mp++;
        }
 
        int i = 0;
        bool flag = true;
 
        // Initialise the hashtable
        // for String s for window m
        for (i = 0; i < m; i++) {
            ms[s[i] - 'A']++;
        }
 
        // Check if current hashtables are same
        // for current window m
 
        for (int j = 0; j < 26; j++)
            if (mp[j] != ms[j])
                flag = false;
 
        // if same, push the index of
        // Starting subString into window m
 
        if (flag)
            ans.Add(0);
 
        // Traverse String s with window m
        for (i = m; i < n; i++) {
            ms[s[i - m] - 'A']--;
            ms[s[i] - 'A']++;
 
            // Check if current hashtables are same
            // for current window m
            if (mp[s[i] - 'A'] == ms[s[i] - 'A']
                && mp[s[i - m] - 'A']
                       == ms[s[i - m] - 'A']) {
                flag = true;
                for (int j = 0; j < 26; j++)
                    if (mp[j] != ms[j])
                        flag = false;
            }
            else
                flag = false;
 
            // if same, push the index
            // of starting subString
            // into answer
            if (flag)
                ans.Add(i - m + 1);
        }
 
        // Return the final vector of indices
        return ans;
    }
 
    // Driver program
    public static void Main()
    {
        string txt = "BACDGABCDA";
        string pat = "ABCD";
        ArrayList indices = findAnagrams(txt, pat);
        Console.Write("[ ");
        foreach(int i in indices) Console.Write(i + " ");
        Console.Write("]");
    }
}
 
// This code is contributed by Samim Hossain Mondal.


Javascript


输出
[ 0 5 6 ]

时间复杂度: O(N)
辅助空间:O(1)