|
| 1 | +import java.util.stream.IntStream; |
| 2 | + |
1 | 3 | class StringAlgorithm { |
2 | 4 | private static int[] saNaive(int[] s) { |
3 | 5 | int n = s.length; |
4 | | - Integer[] _sa = new Integer[n]; |
5 | | - for (int i = 0; i < n; i++) { |
6 | | - _sa[i] = i; |
| 6 | + int[] sa = new int[n]; |
| 7 | + for(int i = 0;i < n;i++){ |
| 8 | + sa[i] = i; |
7 | 9 | } |
8 | | - java.util.Arrays.sort(_sa, (l, r) -> { |
| 10 | + insertionsortUsingComparator(sa, (l, r) -> { |
9 | 11 | while (l < n && r < n) { |
10 | 12 | if (s[l] != s[r]) return s[l] - s[r]; |
11 | 13 | l++; |
12 | 14 | r++; |
13 | 15 | } |
14 | 16 | return -(l - r); |
15 | 17 | }); |
16 | | - int[] sa = new int[n]; |
17 | | - for (int i = 0; i < n; i++) { |
18 | | - sa[i] = _sa[i]; |
19 | | - } |
20 | 18 | return sa; |
21 | 19 | } |
22 | 20 |
|
23 | | - private static int[] saDoubling(int[] s) { |
| 21 | + public static int[] saDoubling(int[] s) { |
24 | 22 | int n = s.length; |
25 | | - Integer[] _sa = new Integer[n]; |
26 | | - for (int i = 0; i < n; i++) { |
27 | | - _sa[i] = i; |
| 23 | + int[] sa = new int[n]; |
| 24 | + for(int i = 0;i < n;i++){ |
| 25 | + sa[i] = i; |
28 | 26 | } |
29 | 27 | int[] rnk = s; |
30 | 28 | int[] tmp = new int[n]; |
31 | 29 |
|
32 | 30 | for (int k = 1; k < n; k *= 2) { |
33 | 31 | final int _k = k; |
34 | 32 | final int[] _rnk = rnk; |
35 | | - java.util.Comparator<Integer> cmp = (x, y) -> { |
| 33 | + java.util.function.IntBinaryOperator cmp = (x, y) -> { |
36 | 34 | if (_rnk[x] != _rnk[y]) return _rnk[x] - _rnk[y]; |
37 | 35 | int rx = x + _k < n ? _rnk[x + _k] : -1; |
38 | 36 | int ry = y + _k < n ? _rnk[y + _k] : -1; |
39 | 37 | return rx - ry; |
40 | 38 | }; |
41 | | - java.util.Arrays.sort(_sa, cmp); |
42 | | - tmp[_sa[0]] = 0; |
| 39 | + insertionsortUsingComparator(sa, cmp); |
| 40 | + tmp[sa[0]] = 0; |
43 | 41 | for (int i = 1; i < n; i++) { |
44 | | - tmp[_sa[i]] = tmp[_sa[i - 1]] + (cmp.compare(_sa[i - 1], _sa[i]) < 0 ? 1 : 0); |
| 42 | + tmp[sa[i]] = tmp[sa[i - 1]] + (cmp.applyAsInt(sa[i - 1], sa[i]) < 0 ? 1 : 0); |
45 | 43 | } |
46 | 44 | int[] buf = tmp; |
47 | 45 | tmp = rnk; |
48 | 46 | rnk = buf; |
49 | 47 | } |
| 48 | + return sa; |
| 49 | + } |
50 | 50 |
|
51 | | - int[] sa = new int[n]; |
52 | | - for (int i = 0; i < n; i++) { |
53 | | - sa[i] = _sa[i]; |
| 51 | + private static void insertionsortUsingComparator(int[] a, java.util.function.IntBinaryOperator comparator) { |
| 52 | + final int n = a.length; |
| 53 | + for (int i = 1; i < n; i++) { |
| 54 | + final int tmp = a[i]; |
| 55 | + if (comparator.applyAsInt(a[i - 1], tmp) > 0) { |
| 56 | + int j = i; |
| 57 | + do { |
| 58 | + a[j] = a[j - 1]; |
| 59 | + j--; |
| 60 | + } while (j > 0 && comparator.applyAsInt(a[j - 1], tmp) > 0); |
| 61 | + a[j] = tmp; |
| 62 | + } |
54 | 63 | } |
55 | | - return sa; |
56 | 64 | } |
57 | 65 |
|
58 | 66 | private static final int THRESHOLD_NAIVE = 10; |
|
0 commit comments