fully implemented the complile and match methods, written some tests for this
Signed-off-by: Lachlan Roberts <lachlan@webtide.com>
This commit is contained in:
parent
1b3ad11ef9
commit
f68cf85e94
|
@ -22,45 +22,28 @@ public class SearchPattern
|
|||
{
|
||||
static final int alphabetSize = 256;
|
||||
int[] table;
|
||||
|
||||
private String pattern;
|
||||
byte[] pattern;
|
||||
|
||||
public int[] getTable(){ return this.table; }
|
||||
|
||||
/**
|
||||
* @param pattern The pattern to search for.
|
||||
* @return A Pattern instance for the search pattern
|
||||
*/
|
||||
static SearchPattern compile(String pattern)
|
||||
static SearchPattern compile(byte[] pattern)
|
||||
{
|
||||
//Create new SearchPattern instance
|
||||
SearchPattern sp = new SearchPattern();
|
||||
sp.pattern = pattern;
|
||||
|
||||
//Copy in the Pattern
|
||||
sp.pattern = pattern.clone();
|
||||
|
||||
/*
|
||||
Build up pre-processed table for this pattern.
|
||||
|
||||
function preprocess(pattern):
|
||||
T ← new table of 256 integers
|
||||
for i from 0 to 256 exclusive
|
||||
T[i] ← length(pattern)
|
||||
for i from 0 to length(pattern) - 1 exclusive
|
||||
T[pattern[i]] ← length(pattern) - 1 - i
|
||||
return T
|
||||
*/
|
||||
|
||||
//Build up the pre-processed table for this pattern.
|
||||
sp.table = new int[alphabetSize];
|
||||
for(int i = 0; i<sp.table.length; ++i){
|
||||
sp.table[i] = pattern.length();
|
||||
}
|
||||
|
||||
/*
|
||||
for i from 0 to length(pattern) - 1 exclusive
|
||||
T[pattern[i]] ← length(pattern) - 1 - i
|
||||
*/
|
||||
for(int i = 0; i<pattern.length(); ++i){
|
||||
int index = pattern;
|
||||
sp.table[index] = pattern.length()-1-i;
|
||||
}
|
||||
for(int i = 0; i<sp.table.length; ++i)
|
||||
sp.table[i] = sp.pattern.length;
|
||||
for(int i = 0; i<sp.pattern.length-1; ++i)
|
||||
sp.table[sp.pattern[i]] = sp.pattern.length-1-i;
|
||||
|
||||
return sp;
|
||||
}
|
||||
|
@ -76,6 +59,15 @@ public class SearchPattern
|
|||
*/
|
||||
public int match(byte[] data, int offset, int length)
|
||||
{
|
||||
int skip = offset;
|
||||
while((skip <= data.length - pattern.length) && (skip+pattern.length <= offset+length))
|
||||
{
|
||||
for(int i = pattern.length-1; data[skip+i] == pattern[i]; i--)
|
||||
if(i==0) return skip;
|
||||
|
||||
skip += table[data[skip + pattern.length - 1]];
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,10 +27,56 @@ public class SearchPatternTest
|
|||
{
|
||||
|
||||
@Test
|
||||
public void test()
|
||||
public void testBasicSearch()
|
||||
{
|
||||
Assert.assertTrue(SearchPattern.compile("lol") == null);
|
||||
System.out.println("Hello World!");
|
||||
String p1 = "truth";
|
||||
String p2 = "evident";
|
||||
String p3 = "we";
|
||||
String d = "we hold these truths to be self evident";
|
||||
|
||||
|
||||
// Testing Compiled Pattern p1 "truth"
|
||||
SearchPattern sp1 = SearchPattern.compile(p1.getBytes());
|
||||
Assert.assertEquals(14,sp1.match(d.getBytes(), 0, d.length()));
|
||||
Assert.assertEquals(14,sp1.match(d.getBytes(),14,p1.length()));
|
||||
Assert.assertEquals(14,sp1.match(d.getBytes(),14,p1.length()+1));
|
||||
Assert.assertEquals(-1,sp1.match(d.getBytes(),14,p1.length()-1));
|
||||
Assert.assertEquals(-1,sp1.match(d.getBytes(),15,d.length()));
|
||||
|
||||
// Testing Compiled Pattern p2 "evident"
|
||||
SearchPattern sp2 = SearchPattern.compile(p2.getBytes());
|
||||
Assert.assertEquals(32,sp2.match(d.getBytes(), 0, d.length()));
|
||||
Assert.assertEquals(32,sp2.match(d.getBytes(),32,p2.length()));
|
||||
Assert.assertEquals(32,sp2.match(d.getBytes(),32,p2.length()+1));
|
||||
Assert.assertEquals(-1,sp2.match(d.getBytes(),32,p2.length()-1));
|
||||
Assert.assertEquals(-1,sp2.match(d.getBytes(),33,d.length()));
|
||||
|
||||
|
||||
// Testing Compiled Pattern p3 "evident"
|
||||
SearchPattern sp3 = SearchPattern.compile(p3.getBytes());
|
||||
Assert.assertEquals( 0,sp3.match(d.getBytes(), 0, d.length()));
|
||||
Assert.assertEquals( 0,sp3.match(d.getBytes(), 0, p3.length()));
|
||||
Assert.assertEquals( 0,sp3.match(d.getBytes(), 0, p3.length()+1));
|
||||
Assert.assertEquals(-1,sp3.match(d.getBytes(), 0, p3.length()-1));
|
||||
Assert.assertEquals(-1,sp3.match(d.getBytes(), 1, d.length()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testDoubleMatch()
|
||||
{
|
||||
String p = "violent";
|
||||
String d = "These violent delights have violent ends.";
|
||||
|
||||
// Testing Compiled Pattern p1 "truth"
|
||||
SearchPattern sp = SearchPattern.compile(p.getBytes());
|
||||
Assert.assertEquals( 6,sp.match(d.getBytes(), 0, d.length()));
|
||||
Assert.assertEquals(-1,sp.match(d.getBytes(), 6, p.length()-1));
|
||||
Assert.assertEquals(28,sp.match(d.getBytes(), 7, d.length()));
|
||||
Assert.assertEquals(28,sp.match(d.getBytes(), 28, d.length()));
|
||||
Assert.assertEquals(-1,sp.match(d.getBytes(), 29, d.length()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue