字谜子串搜索(或搜索所有排列)|设置 2
给定一个文本txt[0..n-1]和一个模式pat[0..m-1] ,编写一个函数search(char pat[], char txt[]) 打印所有出现的pat[]及其txt[]中的排列(或字谜)。您可以假设n > m 。
例子:
Input: txt[] = “BACDGABCDA” pat[] = “ABCD”
Output: Found at Index 0
Found at Index 5
Found at Index 6
Input: txt[] = “AAABABAA” pat[] = “AABA”
Output: Found at Index 0
Found at Index 1
Found at Index 4
方法:目前的方法是基于滑动窗口和哈希表。
- 创建一个哈希表来存储模式中所有字符的哈希
- 创建一个哈希表以存储窗口 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)