首先定义了suffix string 或者说suffix arrary
如果有个数组是 int[] text = {10, 20, 30, 25}
那么 suffix[0] = {10, 20, 30, 25} . 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷
suffix[1] = {20, 30, 25}
suffix[2] = {30, 25}
suffix[3] = {25}
如果对这些数组进行lexical order 的排序,我们可以得到
suffix[0] < suffix[1] < suffix[3] < suffix[2]
问题是:
input: int[] text . more info on 1point3acres.com
output: int[] suffix_array_order
e.g.
input: int[] text = {10, 20, 30, 25} . 鍥磋鎴戜滑@1point 3 acres
output: int[] suffix_array_order = {0, 1, 3, 2}
第二题: input: int[] text, int[] subText
output: boolean isExist;
检查text数组中有没有一个subarray 是subText。要求时间小于O(N^2), N == text.length;
这里假设我们有了第一题的 suffix_array_order.
如果有个数组是 int[] text = {10, 20, 30, 25}
那么 suffix[0] = {10, 20, 30, 25} . 涓€浜�-涓夊垎-鍦帮紝鐙鍙戝竷
suffix[1] = {20, 30, 25}
suffix[2] = {30, 25}
suffix[3] = {25}
如果对这些数组进行lexical order 的排序,我们可以得到
suffix[0] < suffix[1] < suffix[3] < suffix[2]
问题是:
input: int[] text . more info on 1point3acres.com
output: int[] suffix_array_order
e.g.
input: int[] text = {10, 20, 30, 25} . 鍥磋鎴戜滑@1point 3 acres
output: int[] suffix_array_order = {0, 1, 3, 2}
第二题: input: int[] text, int[] subText
output: boolean isExist;
检查text数组中有没有一个subarray 是subText。要求时间小于O(N^2), N == text.length;
这里假设我们有了第一题的 suffix_array_order.
(做法是binary search)
package array;
import java.util.Arrays;
import java.util.Comparator;
//http://www.1point3acres.com/bbs/forum.php?mod=viewthread&tid=125284&extra=page%3D4%26filter%3Dsortid%26sortid%3D311%26searchoption%255B3046%255D%255Bvalue%255D%3D2%26searchoption%255B3046%255D%255Btype%255D%3Dradio&page=1
public class SuffixArray {
public class Index {
int[] suff;
int idx;
Index(int[] _suff, int _idx) {
suff = _suff;
idx = _idx;
}
}
// Sort
int[] suffixOrder(int[] text, int n) {
int[] res = new int[n];
Index[] indices = new Index[n];
for (int i = 0; i < n; i++) {
int[] suffix = Arrays.copyOfRange(text, i, text.length);
indices[i] = new Index(suffix, i);
}
Arrays.sort(indices, new Comparator<Index>() {
public int compare(Index i1, Index i2) {
int p1 = 0;
int p2 = 0;
while (p1 < i1.suff.length && p2 < i2.suff.length) {
if (i1.suff[p1] != i2.suff[p2]) {
return i1.suff[p1] - i2.suff[p2];
} else {
p1++;
p2++;
}
}
if (p2 == i2.suff.length) {
return 1;
}
return -1;
}
});
for (int i = 0; i < n; i++) {
res[i] = indices[i].idx;
}
return res;
}
// Search
boolean search(final int[] text, int n, final int[] sub_text, int m) {
int[] suffix_order = suffixOrder(text, n);
int lo = 0;
int hi = n - 1;
while (lo <= hi) {
int mid = (lo + hi) / 2;
if (mid + m >= n) {
return false;
}
int[] suffix = Arrays.copyOfRange(text, suffix_order[mid], m);
int cmp = compare(suffix, sub_text);
if (cmp == 0) {
return true;
} else if (cmp < 0) {
lo = mid + 1;
} else {
hi = mid - 1;
}
}
return false;
}
private int compare(int[] a, int[] b) {
int i1 = 0, i2 = 0;
while (i1 < a.length && i2 < b.length) {
if (a[i1] != b[i2]) {
return a[i1] - b[i2];
} else {
i1++;
i2++;
}
}
if (i2 == b.length)
return -1;
return 0;
}
public static void main(String[] args) {
int text[] = { 10, 20, 30, 25 };
SuffixArray suffixArray = new SuffixArray();
int[] res = suffixArray.suffixOrder(text, 4);
for (int i : res) {
System.out.print(i);
}
int sub_text[] = { 20, 30 };
boolean search_res = suffixArray.search(text, 4, sub_text, 2);
System.out.print(search_res);
}
}