|
1 | 1 | package ssj.algorithm;
|
2 | 2 |
|
3 |
| -import ssj.algorithm.collections.AVLTree; |
| 3 | +import ssj.algorithm.string.StringUntil; |
4 | 4 |
|
5 | 5 | /**
|
6 | 6 | * Created by shenshijun on 15/2/1.
|
7 | 7 | */
|
8 | 8 | public class Main {
|
9 | 9 |
|
10 | 10 | public static void main(String[] args) {
|
11 |
| - int[] data = new int[]{1, 2, 3, 4, 34, 1, 234}; |
12 |
| - AVLTree<Integer> tree = new AVLTree<>(); |
13 |
| - for (int i : data) { |
14 |
| - tree.add(i); |
| 11 | + System.out.println(StringUntil.search("BBC ABCDAB ABCDABCDABDE", "ABCDABD")); |
| 12 | + } |
| 13 | + |
| 14 | + /** |
| 15 | + * Returns the index within this string of the first occurrence of the |
| 16 | + * specified substring. If it is not a substring, return -1. |
| 17 | + * |
| 18 | + * @param haystack The string to be scanned |
| 19 | + * @param needle The target string to search |
| 20 | + * @return The start index of the substring |
| 21 | + */ |
| 22 | + public static int indexOf(char[] haystack, char[] needle) { |
| 23 | + if (needle.length == 0) { |
<
6D40
/code> | 24 | + return 0; |
| 25 | + } |
| 26 | + int charTable[] = makeCharTable(needle); |
| 27 | + int offsetTable[] = makeOffsetTable(needle); |
| 28 | + for (int i = needle.length - 1, j; i < haystack.length; ) { |
| 29 | + for (j = needle.length - 1; needle[j] == haystack[i]; --i, --j) { |
| 30 | + if (j == 0) { |
| 31 | + return i; |
| 32 | + } |
| 33 | + } |
| 34 | + // i += needle.length - j; // For naive method |
| 35 | + i += Math.max(offsetTable[needle.length - 1 - j], charTable[haystack[i]]); |
| 36 | + } |
| 37 | + return -1; |
| 38 | + } |
| 39 | + |
| 40 | + /** |
| 41 | + * Makes the jump table based on the mismatched character information. |
| 42 | + */ |
| 43 | + private static int[] makeCharTable(char[] needle) { |
| 44 | + final int ALPHABET_SIZE = 256; |
| 45 | + int[] table = new int[ALPHABET_SIZE]; |
| 46 | + for (int i = 0; i < table.length; ++i) { |
| 47 | + table[i] = needle.length; |
| 48 | + } |
| 49 | + for (int i = 0; i < needle.length - 1; ++i) { |
| 50 | + table[needle[i]] = needle.length - 1 - i; |
| 51 | + } |
| 52 | + return table; |
| 53 | + } |
| 54 | + |
| 55 | + /** |
| 56 | + * Makes the jump table based on the scan offset which mismatch occurs. |
| 57 | + */ |
| 58 | + private static int[] makeOffsetTable(char[] needle) { |
| 59 | + int[] table = new int[needle.length]; |
| 60 | + int lastPrefixPosition = needle.length; |
| 61 | + for (int i = needle.length - 1; i >= 0; --i) { |
| 62 | + if (isPrefix(needle, i + 1)) { |
| 63 | + lastPrefixPosition = i + 1; |
| 64 | + } |
| 65 | + table[needle.length - 1 - i] = lastPrefixPosition - i + needle.length - 1; |
| 66 | + } |
| 67 | + for (int i = 0; i < needle.length - 1; ++i) { |
| 68 | + int slen = suffixLength(needle, i); |
| 69 | + table[slen] = needle.length - 1 - i + slen; |
| 70 | + } |
| 71 | + return table; |
| 72 | + } |
| 73 | + |
| 74 | + /** |
| 75 | + * Is needle[p:end] a prefix of needle? |
| 76 | + */ |
| 77 | + private static boolean isPrefix(char[] needle, int p) { |
| 78 | + for (int i = p, j = 0; i < needle.length; ++i, ++j) { |
| 79 | + if (needle[i] != needle[j]) { |
| 80 | + return false; |
| 81 | + } |
| 82 | + } |
| 83 | + return true; |
| 84 | + } |
| 85 | + |
| 86 | + /** |
| 87 | + * Returns the maximum length of the substring ends at p and is a suffix. |
| 88 | + */ |
| 89 | + private static int suffixLength(char[] needle, int p) { |
| 90 | + int len = 0; |
| 91 | + for (int i = p, j = needle.length - 1; |
| 92 | + i >= 0 && needle[i] == needle[j]; --i, --j) { |
| 93 | + len += 1; |
15 | 94 | }
|
16 |
| - System.out.println(tree); |
| 95 | + return len; |
17 | 96 | }
|
18 | 97 | }
|
0 commit comments