1
1
package _16_18_Pattern_Matching ;
2
2
3
3
// Algorithm:
4
- // 0 ) If pattern is all the same letter (aaaaa... or bbbbb...), treat it as a special case.
5
- // 1 ) Invert pattern (if necessary) to have it start with "a" instead of "b"
6
- // 2 ) count numAs, numBs
7
- // 3 ) try maxLengthA = 1 up to max it could validly be
4
+ // 1 ) If pattern is all the same letter (aaaaa... or bbbbb...), treat it as a special case.
5
+ // 2 ) Invert pattern (if necessary) to have it start with "a" instead of "b"
6
+ // 3 ) count numAs, numBs
7
+ // 4 ) try maxLengthA = 1 up to max it could validly be
8
8
// - for each maxLengthA, calculate maxLengthB
9
9
// - use a helper function: checkMatch(String value, String pattern, int aLength, int bLength)
10
10
11
11
public class PatternMatching {
12
12
13
- public static boolean matches (String value , String pattern ) {
14
- /* Special case: all same character in pattern */
15
- if (pattern .indexOf ('a' ) == -1 || pattern .indexOf ('b' ) == -1 ) {
16
- return value .length () % pattern .length () == 0 ; // wrong. must check if pattern properly repeats in value.
13
+ public static boolean matches (String str , String pattern ) {
14
+ if (str == null || pattern == null || pattern .length () > str .length ()) {
15
+ return false ;
16
+ } else if (pattern .length () == 0 ) {
17
+ return str .length () == 0 ;
18
+ } else if (pattern .indexOf ('a' ) == -1 || pattern .indexOf ('b' ) == -1 ) {
19
+ return checkMatchRepeatingWord (str , pattern );
17
20
}
18
21
19
- pattern = invert (pattern );
22
+ pattern = invertIfNecessary (pattern );
20
23
int numAs = countOf (pattern , 'a' );
21
24
int numBs = pattern .length () - numAs ;
22
- int maxLengthA = value .length () / numAs ;
25
+ int maxLengthA = str .length () / numAs ;
23
26
for (int lengthA = 1 ; lengthA <= maxLengthA ; lengthA ++) {
24
- int charsForB = value .length () - lengthA * numAs ;
27
+ int charsForB = str .length () - lengthA * numAs ;
25
28
if (charsForB % numBs != 0 ) {
26
29
continue ;
27
30
}
28
31
int lengthB = charsForB / numBs ;
29
- if (checkMatch (value , pattern , lengthA , lengthB )) {
32
+ if (checkMatch (str , pattern , lengthA , lengthB )) {
30
33
return true ;
31
34
}
32
35
}
33
36
return false ;
34
37
}
35
38
36
- /* Changes pattern (if necessary) to start with 'a' instead of 'b'. Example: bbaba becomes aabab */
37
- private static String invert (String pattern ) {
39
+ // Changes pattern (if necessary) to start with 'a' instead of 'b'. Example: bbaba becomes aabab
40
+ private static String invertIfNecessary (String pattern ) {
38
41
if (pattern .charAt (0 ) == 'a' ) {
39
42
return pattern ;
40
43
}
@@ -59,22 +62,33 @@ private static int countOf(String str, char ch) {
59
62
return count ;
60
63
}
61
64
62
- private static boolean checkMatch (String value , String pattern , int aLength , int bLength ) {
63
- /* Grab the 2 words matching "a" and "b" */
65
+ private static boolean checkMatchRepeatingWord (String str , String pattern ) {
66
+ int wordLength = str .length () / pattern .length ();
67
+ String word = str .substring (0 , wordLength );
68
+ for (int i = 0 ; i < str .length (); i += word .length ()) {
69
+ if (!str .substring (i , i + word .length ()).equals (word )) {
70
+ return false ;
71
+ }
72
+ }
73
+ return true ;
74
+ }
75
+
76
+ private static boolean checkMatch (String str , String pattern , int aLength , int bLength ) {
77
+ // Grab the 2 words matching "a" and "b"
64
78
int firstBinPattern = pattern .indexOf ('b' );
65
- int firstBinValue = firstBinPattern * aLength ;
66
- String aWord = value .substring (0 , aLength );
67
- String bWord = value .substring (firstBinValue , firstBinValue + bLength );
79
+ int firstBinValue = firstBinPattern * aLength ;
80
+ String aWord = str .substring (0 , aLength );
81
+ String bWord = str .substring (firstBinValue , firstBinValue + bLength );
68
82
69
83
int i = 0 ;
70
84
for (int j = 0 ; j < pattern .length (); j ++) {
71
85
if (pattern .charAt (j ) == 'a' ) {
72
- if (!value .substring (i , i + aLength ).equals (aWord )) {
86
+ if (!str .substring (i , i + aLength ).equals (aWord )) {
73
87
return false ;
74
88
}
75
89
i += aLength ;
76
90
} else if (pattern .charAt (j ) == 'b' ) {
77
- if (!value .substring (i , i + bLength ).equals (bWord )) {
91
+ if (!str .substring (i , i + bLength ).equals (bWord )) {
78
92
return false ;
79
93
}
80
94
i += bLength ;
@@ -85,3 +99,4 @@ private static boolean checkMatch(String value, String pattern, int aLength, int
85
99
}
86
100
87
101
// Time Complexity: O(n^2)
102
+ // Space Complexity: O(n)
0 commit comments