Site Search:

substring search

Problem:

Given a word, find the first matching index in a string.
For example, given a word "needle", the first matching index in "a needle in a needleless haystack" is 2.

Solution:


class Solution {
    //time worst O(MN), typical O(1.1N), space O(1)
    public static int brutalForce(String pattern, String txt) {
        int N = txt.length();
        int M = pattern.length();
        int i, j = 0;
        for(i = 0; i < N - M; i++) {
            for(j = 0; j < M; j++) {
                if(pattern.charAt(j) != txt.charAt(i + j)) break;
            }
            if(j == M) return i;
        }
        return -1;
    }
    public static void main(String...args) {
        String pattern = "needle";
        String txt = "a well needed needle in the haystack";
        String txt2 = "a stick in the haystack";
        System.out.println(brutalForce(pattern, txt));
        BoyerMoore bm = new BoyerMoore(pattern);
        System.out.println(bm.match(txt));
        System.out.println(brutalForce(pattern, txt2));
        System.out.println(bm.match(txt2));
    }
    
    //time worst O(NM), typical O(N/M), space O(R)
    private static class BoyerMoore{
        private int[] right;
        String pattern;
        public BoyerMoore(String pattern) {
            int R = 256;
            this.pattern = pattern;
            right = new int[R];
            int M = pattern.length();
            for(int i = 0; i < R; i++) {
                right[i] = -1;
            }
            for(int i = 0; i < M; i++) {
                right[pattern.charAt(i)] = i; 
            }
        }
        public int match(String txt) {
            int N = txt.length();
            int M = pattern.length();
            int skip;
            for(int i = 0; i < N - M; i += skip) {
                skip = 0;
                for(int j = M - 1; j >= 0; j--) {
                    if(txt.charAt(i + j) != pattern.charAt(j)) {
                        skip = j - right[txt.charAt(i + j)];
                        if(skip < 1) skip = 1;
                        break;
                    }
                }
                if(skip == 0) return i;
            }
            return -1;
        }
    }
}