算法习题之DC3生成后缀数组

本文详细介绍了如何运用DC3算法生成后缀数组的步骤,包括精确排名、桶排序、ASCII隔开和合并策略。通过示例习题解释了如何找到字符串的字典序最大子串。
摘要由CSDN通过智能技术生成

介绍用DC3算法生成后缀数组的流程

1.得到S12的精确排名(取S12的前三位进行桶排序)
2.s1按照原来在数组的顺序放在左边(放第一步的排名),s2按照原来在数组的顺序放在右边中间(放第一步的排名)用最小的ASCII隔开(如果第一步得到精确的排名,跳过第2步)
3.得到s0精确排名(每一个S0的数变为S0位置的数 + 紧跟当前位置数的排名)
4.得到总排名(S0和S12进行merge,如果是S0和S1merge:S0和S1当前位置的数字做比较,下一位用S12的排名做比较,如果是S0和S2merge:S0和S1当前位置的数字做比较,下一位还用当前字符做比较,下下一位用排名做比较)

DC3模板

// arr = [a,a,b,a]
	//        0 1 2 3
	// 第几名在原数组的位置
	// sa = [3,0,1,2]
	//       0 1 2 3
	// 原数组位置是第几名
	// rank = [1,2,3,0]
	//         0 1 2 3

	public int[] sa;

	public int[] rank;

	public int[] height;

	// 构造方法的约定:
	// 数组叫nums,如果你是字符串,请转成整型数组nums
	// 数组中,最小值>=1
	// 如果不满足,处理成满足的,也不会影响使用
	// max, nums里面最大值是多少
	public DC3(int[] nums, int max) {
		sa = sa(nums, max);
		rank = rank();
		height = height(nums);
	}

	private int[] sa(int[] nums, int max) {
		int n = nums.length;
		int[] arr = new int[n + 3];
		for (int i = 0; i < n; i++) {
			arr[i] = nums[i];
		}
		return skew(arr, n, max);
	}

	private int[] skew(int[] nums, int n, int K) {
		int n0 = (n + 2) / 3, n1 = (n + 1) / 3, n2 = n / 3, n02 = n0 + n2;
		int[] s12 = new int[n02 + 3], sa12 = new int[n02 + 3];
		for (int i = 0, j = 0; i < n + (n0 - n1); ++i) {
			if (0 != i % 3) {
				s12[j++] = i;
			}
		}
		radixPass(nums, s12, sa12, 2, n02, K);
		radixPass(nums, sa12, s12, 1, n02, K);
		radixPass(nums, s12, sa12, 0, n02, K);
		int name = 0, c0 = -1, c1 = -1, c2 = -1;
		for (int i = 0; i < n02; ++i) {
			if (c0 != nums[sa12[i]] || c1 != nums[sa12[i] + 1] || c2 != nums[sa12[i] + 2]) {
				name++;
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值