Skip to content

Commit 9fa6d68

Browse files
author
Samuel Facchinello
committed
refactor searchPattern with private class
1 parent bdd4d62 commit 9fa6d68

File tree

1 file changed

+49
-25
lines changed

1 file changed

+49
-25
lines changed

src/main/java/com/thealgorithms/others/StringMatchFiniteAutomata.java

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@ public final class StringMatchFiniteAutomata {
1313
// Constants
1414
private static final int CHARS = 256; // Total number of characters in the input alphabet
1515

16-
// Finite automata table
17-
private static int[][] finiteAutomata;
18-
1916
// Private constructor to prevent instantiation
2017
private StringMatchFiniteAutomata() {
2118
}
@@ -26,25 +23,16 @@ private StringMatchFiniteAutomata() {
2623
* @param text The text to search within.
2724
* @param pattern The pattern to search for.
2825
*/
29-
public static Set<Integer> searchPattern(String text, String pattern) {
30-
Set<Integer> indexFound = new TreeSet<>();
31-
int patternLength = pattern.length();
32-
int textLength = text.length();
33-
34-
// Initialize finite automata table
35-
finiteAutomata = new int[patternLength + 1][CHARS];
36-
37-
// Preprocess the pattern to create the finite automata table
38-
computeFiniteAutomata(pattern, patternLength);
39-
40-
int state = 0; // Initial state
26+
public static Set<Integer> searchPattern(final String text, final String pattern) {
27+
final var stateTransitionTable = computeStateTransitionTable(pattern);
28+
FiniteAutomata finiteAutomata = new FiniteAutomata(stateTransitionTable);
4129

42-
// Process the text over the finite automata
43-
for (int i = 0; i < textLength; i++) {
44-
state = finiteAutomata[state][text.charAt(i)];
30+
Set<Integer> indexFound = new TreeSet<>();
31+
for (int i = 0; i < text.length(); i++) {
32+
finiteAutomata.consume(text.charAt(i));
4533

46-
if (state == patternLength) {
47-
indexFound.add(i - patternLength + 1);
34+
if (finiteAutomata.getState() == pattern.length()) {
35+
indexFound.add(i - pattern.length() + 1);
4836
}
4937
}
5038
return indexFound;
@@ -53,15 +41,20 @@ public static Set<Integer> searchPattern(String text, String pattern) {
5341
/**
5442
* Computes the finite automata table for the given pattern.
5543
*
56-
* @param pattern The pattern to preprocess.
57-
* @param patternLength The length of the pattern.
44+
* @param pattern The pattern to preprocess.
45+
* @return The state transition table.
5846
*/
59-
private static void computeFiniteAutomata(String pattern, int patternLength) {
47+
private static int[][] computeStateTransitionTable(final String pattern) {
48+
int patternLength = pattern.length();
49+
int[][] stateTransitionTable = new int[patternLength + 1][CHARS];
50+
6051
for (int state = 0; state <= patternLength; ++state) {
6152
for (int x = 0; x < CHARS; ++x) {
62-
finiteAutomata[state][x] = getNextState(pattern, patternLength, state, x);
53+
stateTransitionTable[state][x] = getNextState(pattern, patternLength, state, x);
6354
}
6455
}
56+
57+
return stateTransitionTable;
6558
}
6659

6760
/**
@@ -73,7 +66,7 @@ private static void computeFiniteAutomata(String pattern, int patternLength) {
7366
* @param x The current character from the input alphabet.
7467
* @return The next state.
7568
*/
76-
private static int getNextState(String pattern, int patternLength, int state, int x) {
69+
private static int getNextState(final String pattern, final int patternLength, final int state, final int x) {
7770
// If the current state is less than the length of the pattern
7871
// and the character matches the pattern character, go to the next state
7972
if (state < patternLength && x == pattern.charAt(state)) {
@@ -99,4 +92,35 @@ private static int getNextState(String pattern, int patternLength, int state, in
9992
// If no prefix which is also a suffix is found, return 0
10093
return 0;
10194
}
95+
96+
/**
97+
* A class representing the finite automata for pattern matching.
98+
*/
99+
private static class FiniteAutomata {
100+
private int state;
101+
private final int[][] stateTransitionTable;
102+
103+
public FiniteAutomata(int[][] stateTransitionTable) {
104+
this.stateTransitionTable = stateTransitionTable;
105+
this.state = 0; // Initial state
106+
}
107+
108+
/**
109+
* Consumes an input character and transitions to the next state.
110+
*
111+
* @param input The input character.
112+
*/
113+
public void consume(final char input) {
114+
state = stateTransitionTable[state][input];
115+
}
116+
117+
/**
118+
* Gets the current state of the finite automata.
119+
*
120+
* @return The current state.
121+
*/
122+
public int getState() {
123+
return state;
124+
}
125+
}
102126
}

0 commit comments

Comments
 (0)