字符串有很多模式搜索算法。 KMP算法,Z算法Rabin Karp算法等是朴素模式搜索算法的优化。
朴素模式搜索算法:
Input : "AABACACAACAC"
Pattern : "CAC"
Output : [4,9]
AABACACAACAC
执行:
Java
// Java Program to Search for a Pattern String in the Input
// String returning the indicies
// Importing input java classes
import java.io.*;
// Main class
public class GFG {
// Method 1
// To find pattern in the string
static void search(String s, String pattern)
{
// Iterating over the string in which to be searched
// for using the length() method
for (int i = 0; i <= s.length() - pattern.length();
++i) {
int check = 1;
// Iterating over the string for which is to be
// searched using the length() method
for (int j = 0; j < pattern.length(); ++j) {
// Now, checking the elements of pattern
// with the given string using theb charAt()
// method
if (s.charAt(i + j) != pattern.charAt(j)) {
// Setting check to zero as pattern is
// not detected here
check = 0;
// Break statement to hault
// execution of code
break;
}
}
// Now if the check remains same as declared
// then pattern is detedcted at least once
if (check == 1) {
// Printing the position(index) of the
// pattern string in the input string
System.out.print(i + " , ");
}
}
}
// Metohd 2
// Main driver method
public static void main(String[] args)
{
// Given custom input string
String s = "AABACACAACAC";
// Pattern to be looked after in
// the above input string
String pattern = "CAC";
// Display message for interpreting the indicies
// ai where if the pattern exists
System.out.print(
"Pattern is found at the indicies : ");
// Calling the above search() method
// in the main() method
search(s, pattern);
}
}
Java
// Java Program to illsutating Simple Rolling Hashing
// Importing input output classes
import java.io.*;
// Main class
class GFG {
// Method 1
// To search the pattern
static void search(String S, String pattern)
{
// Declaring and initializing the hash values
int hash1 = 0;
int hash2 = 0;
// Iterating over the pattern string to be matched
// over
for (int i = 0; i < pattern.length(); ++i) {
// Storting the hash value of the pattern
hash1 += pattern.charAt(i) - 'A';
// Storing First hash value of the string
hash2 += S.charAt(i) - 'A';
}
// Initially declaring with zero
int j = 0;
// Iterating over the pattern string to vheckout
// hash values
for (int i = 0; i < S.length() - pattern.length();
++i) {
// Checking the hash value
if (hash2 == hash1) {
// Checking the value
for (j = 0; j < pattern.length(); ++j) {
// Checking for detectio of pattern in a
// pattern
if (pattern.charAt(j)
!= S.charAt(i + j)) {
// Break statement to hault the
// execution of program as no
// pattern found
break;
}
}
}
// If execution is not stopped means
// pattern(sub-string) is present
// So now simply detecting for one or more
// ocurences inbetween pattern string using the
// length() method
if (j == pattern.length()) {
// Pattern is detected so printing the index
System.out.println(i);
}
// Roll the hash value over the string detected
hash2 = (int)((hash2) - (S.charAt(i) - 'A'))
+ S.charAt(i + pattern.length()) - 'A';
}
}
// Method 2
// Main driver method
public static void main(String[] args)
{
// Input string to be traversed
String S = "CACCACA";
// Pattern string to be checked
String pattern = "CAC";
// Calliing the above search() method(Method1)
// in the main() method
search(S, pattern);
}
}
输出
Pattern is found at the indicies : 4 , 9 ,
输出说明:
The above algorithm for pattern searching is the basic algorithm the worst as the average time complexity of this algorithm is O(n×m) where n is the pattern and m is the given string.
我们如何降低该算法的复杂性?
借助滚动哈希是可能的。 Rabin Karp算法是朴素算法的优化算法之一,它通过在字符串滚动并搜索模式来执行搜索。
插图:
Input: txt[] = "THIS IS A TEST TEXT"
pat[] = "TEST"
Output: Pattern found at index 10
Input: txt[] = "AABAACAADAABAABA"
pat[] = "AABA"
Output: Pattern found at index 0
Pattern found at index 9
Pattern found at index 12
程序:
- 计算模式的哈希值(通过创建自己的哈希函数或公式来确定每个字符的哈希值)
- 遍历字符串检查匹配模式的大小所生成的每个子字符串的哈希值(如果匹配的话),并检查模式的每个字符,如果所有匹配的字符都打印字符串的起始索引。
- 如果没有跳过第一个字符,添加下一个字符,我们不计算字符串中的下串的散列值的散列值相匹配转移到下一个字符只有我们滑动窗口跳过第一个字符,并添加通过计算其哈希值(即滚动哈希)来确定窗口中的最后一个字符。
执行:
假设长度为2的模式的简单滚动算法
- 初始化temp = 4(1 + 3)
- 将哈希值滚动到下一个元素。
- 循环’i'<= Array.length-pattern.length
- 从temp变量中删除第一个元素,然后在temp变量中添加下一个元素。 temp = temp-Array [i] + Array [i.pattern.length()]
Java
// Java Program to illsutating Simple Rolling Hashing
// Importing input output classes
import java.io.*;
// Main class
class GFG {
// Method 1
// To search the pattern
static void search(String S, String pattern)
{
// Declaring and initializing the hash values
int hash1 = 0;
int hash2 = 0;
// Iterating over the pattern string to be matched
// over
for (int i = 0; i < pattern.length(); ++i) {
// Storting the hash value of the pattern
hash1 += pattern.charAt(i) - 'A';
// Storing First hash value of the string
hash2 += S.charAt(i) - 'A';
}
// Initially declaring with zero
int j = 0;
// Iterating over the pattern string to vheckout
// hash values
for (int i = 0; i < S.length() - pattern.length();
++i) {
// Checking the hash value
if (hash2 == hash1) {
// Checking the value
for (j = 0; j < pattern.length(); ++j) {
// Checking for detectio of pattern in a
// pattern
if (pattern.charAt(j)
!= S.charAt(i + j)) {
// Break statement to hault the
// execution of program as no
// pattern found
break;
}
}
}
// If execution is not stopped means
// pattern(sub-string) is present
// So now simply detecting for one or more
// ocurences inbetween pattern string using the
// length() method
if (j == pattern.length()) {
// Pattern is detected so printing the index
System.out.println(i);
}
// Roll the hash value over the string detected
hash2 = (int)((hash2) - (S.charAt(i) - 'A'))
+ S.charAt(i + pattern.length()) - 'A';
}
}
// Method 2
// Main driver method
public static void main(String[] args)
{
// Input string to be traversed
String S = "CACCACA";
// Pattern string to be checked
String pattern = "CAC";
// Calliing the above search() method(Method1)
// in the main() method
search(S, pattern);
}
}
输出
0
3