Exemple #1
0
static void radix_sort(const Value *A, Index n, Index stride,
                       Value *out, Value *work)
{
  Index count[DIGITS][DIGIT_VALUES];
  const Value *end = A+n*stride;
  Value bitorkey = radix_count(A, end, stride, count);
  unsigned shift[DIGITS]; Index *offsets[DIGITS];
  unsigned digits = radix_zeros(bitorkey,count,shift,offsets);
  if(digits==0) {
    memset(out,0,sizeof(Value)*n);
  } else {
    Value *src, *dst; unsigned d;
    if((digits&1)==1) src=out,dst=work;
                 else dst=out,src=work;
    radix_pass(A,end,stride,shift[0],offsets[0],src);
    for(d=1;d!=digits;++d) {
      Value *t;
      radix_pass(src,src+n,1,shift[d],offsets[d],dst);
      t=src,src=dst,dst=t;
    }
  }
}
void compute_suffix_array(const size_t *const s, size_t *const suffix_array, const size_t length, const unsigned int max_val) {
	const size_t L0 = (length + 2) / 3, L1 = (length + 1) / 3, L2 = length / 3, L02 = L0 + L2;
	size_t i, j, label, p, t, k, c0, c1, c2, *const s12 = (size_t *)malloc((L02 + 3) * sizeof(size_t)), *const suffix_array12 = (size_t *)malloc((L02 + 3) * sizeof(size_t)), *const s0 = (size_t *)malloc(L0 * sizeof(size_t)), *const suffix_array0 = (size_t *)malloc(L0 * sizeof(size_t));
	s12[L02] = s12[L02 + 1] = s12[L02 + 2] = 0;  /* pading with 0s */
	suffix_array12[L02] = suffix_array12[L02 + 1] = suffix_array12[L02 + 2] = 0;
	for (i = 0, j = 0; i < length + L0 - L1; ++i) if (i % 3) s12[j++] = i;
	radix_pass(s12, suffix_array12, s + 2, L02, max_val);
	radix_pass(suffix_array12, s12, s + 1, L02, max_val);
	radix_pass(s12, suffix_array12, s, L02, max_val);
	label = 0, c0 = c1 = c2 = UINT_MAX;
	for (i = 0; i < L02; ++i) {
		if (s[suffix_array12[i]] != c0 || s[suffix_array12[i] + 1] != c1 || s[suffix_array12[i] + 2] != c2) {
			++label;
			c0 = s[suffix_array12[i]];
			c1 = s[suffix_array12[i] + 1];
			c2 = s[suffix_array12[i] + 2];
		}
		if (1 == suffix_array12[i] % 3) s12[suffix_array12[i] / 3] = label; else s12[suffix_array12[i] / 3 + L0] = label;
	}
	if (label < L02) {
		compute_suffix_array(s12, suffix_array12, L02, label);
		for (i = 0; i < L02; ++i) s12[suffix_array12[i]] = i + 1;
	} else
		for (i = 0; i < L02; ++i) suffix_array12[s12[i] - 1] = i;
	for (i = 0, j = 0; i < L02; ++i) if (suffix_array12[i] < L0) s0[j++] = 3 * suffix_array12[i];
	radix_pass(s0, suffix_array0, s, L0, max_val);
	for (p = 0, t = L0 - L1, k = 0; k < length; ++k) {
		i = (suffix_array12[t] < L0 ? suffix_array12[t] * 3 + 1 : (suffix_array12[t] - L0) * 3 + 2);
		j = suffix_array0[p];
		if (suffix_array12[t] < L0 ? leq2(s[i], s12[suffix_array12[t] + L0], s[j], s12[j / 3]) : leq3(s[i], s[i + 1], s12[suffix_array12[t] - L0 + 1], s[j], s[j + 1], s12[j / 3 + L0])) {
			suffix_array[k] = i; ++t;
			if(t == L02) for (++k; p < L0; ++p, ++k) suffix_array[k] = suffix_array0[p];
		} else {
			suffix_array[k] = j; ++p;
			if (p == L0) for (++k; t < L02; ++t, ++k) suffix_array[k] = (suffix_array12[t] < L0 ? suffix_array12[t] * 3 + 1 : (suffix_array12[t] - L0) * 3 + 2);
		}
	}
	free(s12), free(suffix_array12), free(suffix_array0), free(s0);
}