-
Notifications
You must be signed in to change notification settings - Fork 47
/
BoyerMoore.java
151 lines (137 loc) · 4.23 KB
/
BoyerMoore.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//BoyerMoore字符串匹配算法(启发式地处理不匹配的字符)
public class BoyerMoore
{
private final int R; // the radix
private int[] right; // the bad-character skip array
private char[] pattern; // store the pattern as a character array
private String pat; // or as a string
/**
* Preprocesses the pattern string.
*
* @param pat the pattern string
*/
public BoyerMoore(String pat)
{
this.R = 256;
this.pat = pat;
// position of rightmost occurrence of c in the pattern
right = new int[R];
for (int c = 0; c < R; c++)
{
right[c] = -1; //不包含在模式字符串中的字符的值为-1
}
for (int j = 0; j < pat.length(); j++)
{//包含在模式字符串中的字符的值为它在其中出现的最右位置
right[pat.charAt(j)] = j;
}
}
/**
* Preprocesses the pattern string.
*
* @param pattern the pattern string
* @param R the alphabet size
*/
public BoyerMoore(char[] pattern, int R)
{
this.R = R;
this.pattern = new char[pattern.length];
for (int j = 0; j < pattern.length; j++)
{
this.pattern[j] = pattern[j];
}
// position of rightmost occurrence of c in the pattern
right = new int[R];
for (int c = 0; c < R; c++)
{
right[c] = -1;
}
for (int j = 0; j < pattern.length; j++)
{
right[pattern[j]] = j;
}
}
/**
* Returns the index of the first occurrrence of the pattern string
* in the text string.
*
* @param txt the text string
* @return the index of the first occurrence of the pattern string
* in the text string; n if no such match
*/
public int search(String txt)
{
int m = pat.length();
int n = txt.length();
int skip;
for (int i = 0; i <= n - m; i += skip)
{
skip = 0;
for (int j = m-1; j >= 0; j--)
{
if (pat.charAt(j) != txt.charAt(i+j))
{
skip = Math.max(1, j - right[txt.charAt(i+j)]);
break;
}
}
if (skip == 0) return i; // found
}
return n; // not found
}
/**
* Returns the index of the first occurrrence of the pattern string
* in the text string.
*
* @param text the text string
* @return the index of the first occurrence of the pattern string
* in the text string; n if no such match
*/
public int search(char[] text)
{
int m = pattern.length;
int n = text.length;
int skip;
for (int i = 0; i <= n - m; i += skip)
{
skip = 0;
for (int j = m-1; j >= 0; j--)
{
if (pattern[j] != text[i+j])
{
skip = Math.max(1, j - right[text[i+j]]);
break;
}
}
if (skip == 0) return i; // found
}
return n; // not found
}
/**
* Takes a pattern string and an input string as command-line arguments;
* searches for the pattern string in the text string; and prints
* the first occurrence of the pattern string in the text string.
*
* @param args the command-line arguments
*/
public static void main(String[] args)
{
String pat = "AACAA";
String txt = "AABRAACADABRAACAADABRA";
char[] pattern = pat.toCharArray();
char[] text = txt.toCharArray();
BoyerMoore boyermoore1 = new BoyerMoore(pat);
BoyerMoore boyermoore2 = new BoyerMoore(pattern, 256);
int offset1 = boyermoore1.search(txt);
int offset2 = boyermoore2.search(text);
// print results
System.out.println("text: " + txt);
System.out.print("pattern: ");
for (int i = 0; i < offset1; i++)
System.out.print(" ");
System.out.println(pat);
System.out.print("pattern: ");
for (int i = 0; i < offset2; i++)
System.out.print(" ");
System.out.println(pat);
}
}