
/**
 * Boyer and Moore pattern searching 
 * 
 * @author McKinley & Coons
 * @version April 2007
 */
public class BMSearch
{

    public static void main(String[] args) throws Exception {
       // English character set letters, numbers punctuation
       int MAXCHAR = 256;
       
       // pattern and text
       String pattern = new String("example");
       String text = new String("This is a simple example with two examples.");
       int m = pattern.length();
       int n = text.length();

       // make an array to look up all characters in
       int[] skip = new int[MAXCHAR];
       int k, i, j;
       int compare = 0;
       
       // initialize skip values to m
       for (k=0; k < MAXCHAR; k++) {
            skip[k] = m;
        }
        
        // Set up skip array
        //   for each character (charAt[k]) in the string, skip to align it with a 
        //   matching character 
        //   overwrite repeats with the skip value for the last occurance
        for (k = 0; k < m - 1; k++) {
            skip[pattern.charAt(k)] = m - k - 1;
        }
        
        // Start at m-1, no match? skip[text.charAt(k)]
        boolean match = false;
        for (k = m - 1; k < n; k += skip[text.charAt(k)]) {
            compare++;
            i = k;
            // find matches!
            for (j = m-1;  (j >= 0) && (text.charAt(i) == pattern.charAt(j)); j--) {
                i--;
                compare++;
            }
            if (j == -1) {
               System.out.println ("Match at position " + (i+1) );
               match = true;
            } 
        }
        // print skip array, pattern, text, etc.
        System.out.print("\n\nSkip array: ");
        for (i = 0; i < skip.length; i++) {
            System.out.print(skip[i] + " ");
        }
        System.out.println();
        for (i = 0; i < skip.length; i++) {
            if (skip[i] != m) {
                char c = (char) i;
                System.out.println("skip of character " +  c + " is " + skip[i]);
            }
        }        
        System.out.println("\nPattern: " + pattern);
        System.out.println("\nText: " + text);

        System.out.println("\nPattern length: " + m + ". String length: " + n + ".");
        System.out.println(compare + " Comparisons were made.");
        if (!match) { System.out.println("No match. "); }
    }
}
