suffix arrary

63 篇文章 0 订阅
首先定义了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.

(做法是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);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值