Skip to content

Commit 6cb6ea6

Browse files
committed
Construct the Suffix Array of a Long String using LCP Array
1 parent 8dfecaf commit 6cb6ea6

File tree

2 files changed

+176
-0
lines changed

2 files changed

+176
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
namespace AlgorithmsOnStrin_W4Q2
6+
{
7+
public class W4Q2
8+
{
9+
public static void Main()
10+
{
11+
string text = Console.ReadLine();
12+
long[] order = SortCharacters(text);
13+
long[] _class = ComputeCharClasses(text, order);
14+
long L = 1;
15+
while (L < text.Length)
16+
{
17+
order = SortDoubled(text, L, ref order, ref _class);
18+
_class = UpdateClasses(ref order, ref _class, L);
19+
L *= 2;
20+
}
21+
for (int i = 0; i < order.Length; i++)
22+
{
23+
Console.Write(order[i] + " ");
24+
}
25+
}
26+
public static long[] SortCharacters(string S)
27+
{
28+
int n = S.Length;
29+
long[] order = new long[n];
30+
long[] count = new long[256];
31+
for (int i = 0; i < n; i++) count[S[i]]++;
32+
for (int j = 1; j < 256; j++) count[j] += count[j - 1];
33+
for (int i = n - 1; i >= 0; i--)
34+
{
35+
char c = S[i];
36+
count[c]--;
37+
order[count[c]] = i;
38+
}
39+
return order;
40+
}
41+
public static long[] ComputeCharClasses(string S, long[] order)
42+
{
43+
int n = S.Length;
44+
long[] _classes = new long[n];
45+
_classes[order[0]] = 0;
46+
for (int i = 1; i < n; i++)
47+
{
48+
if (S[(int)order[i]] != S[(int)order[i - 1]]) _classes[order[i]] = _classes[order[i - 1]] + 1;
49+
else _classes[order[i]] = _classes[order[i - 1]];
50+
}
51+
return _classes;
52+
}
53+
public static long[] SortDoubled(string S, long L, ref long[] order, ref long[] _class)
54+
{
55+
int n = S.Length;
56+
long[] count = new long[n];
57+
long[] newOrder = new long[n];
58+
for (int i = 0; i < n; i++) count[_class[i]]++;
59+
for (int i = 1; i < n; i++) count[i] += count[i - 1];
60+
for (int i = n - 1; i >= 0; i--)
61+
{
62+
long start = (order[i] - L + n) % n;
63+
long cl = _class[(int)start];
64+
count[cl]--;
65+
newOrder[count[cl]] = start;
66+
}
67+
return newOrder;
68+
}
69+
public static long[] UpdateClasses(ref long[] newOrder, ref long[] _class, long L)
70+
{
71+
int n = newOrder.Length;
72+
long[] newClass = new long[n];
73+
newClass[newOrder[0]] = 0;
74+
for (int i = 1; i < n; i++)
75+
{
76+
long cur = newOrder[i];
77+
long prev = newOrder[i - 1];
78+
long mid = (cur + L) % n;
79+
long midPrev = (prev + L) % n;
80+
if (_class[cur] != _class[prev] || _class[mid] != _class[midPrev]) newClass[cur] = newClass[prev] + 1;
81+
else newClass[cur] = newClass[prev];
82+
}
83+
return newClass;
84+
}
85+
}
86+
87+
88+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
namespace AlgorithmsOnStrin_W4Q2
6+
{
7+
public class W4Q2
8+
{
9+
public static void Main()
10+
{
11+
string text = Console.ReadLine();
12+
long[] order = SortCharacters(text);
13+
long[] _class = ComputeCharClasses(text, order);
14+
long L = 1;
15+
while (L < text.Length)
16+
{
17+
order = SortDoubled(text, L, ref order, ref _class);
18+
_class = UpdateClasses(ref order, ref _class, L);
19+
L *= 2;
20+
}
21+
for (int i = 0; i < order.Length; i++)
22+
{
23+
Console.Write(order[i] + " ");
24+
}
25+
}
26+
public static long[] SortCharacters(string S)
27+
{
28+
int n = S.Length;
29+
long[] order = new long[n];
30+
long[] count = new long[256];
31+
for (int i = 0; i < n; i++) count[S[i]]++;
32+
for (int j = 1; j < 256; j++) count[j] += count[j - 1];
33+
for (int i = n - 1; i >= 0; i--)
34+
{
35+
char c = S[i];
36+
count[c]--;
37+
order[count[c]] = i;
38+
}
39+
return order;
40+
}
41+
public static long[] ComputeCharClasses(string S, long[] order)
42+
{
43+
int n = S.Length;
44+
long[] _classes = new long[n];
45+
_classes[order[0]] = 0;
46+
for (int i = 1; i < n; i++)
47+
{
48+
if (S[(int)order[i]] != S[(int)order[i - 1]]) _classes[order[i]] = _classes[order[i - 1]] + 1;
49+
else _classes[order[i]] = _classes[order[i - 1]];
50+
}
51+
return _classes;
52+
}
53+
public static long[] SortDoubled(string S, long L, ref long[] order, ref long[] _class)
54+
{
55+
int n = S.Length;
56+
long[] count = new long[n];
57+
long[] newOrder = new long[n];
58+
for (int i = 0; i < n; i++) count[_class[i]]++;
59+
for (int i = 1; i < n; i++) count[i] += count[i - 1];
60+
for (int i = n - 1; i >= 0; i--)
61+
{
62+
long start = (order[i] - L + n) % n;
63+
long cl = _class[(int)start];
64+
count[cl]--;
65+
newOrder[count[cl]] = start;
66+
}
67+
return newOrder;
68+
}
69+
public static long[] UpdateClasses(ref long[] newOrder, ref long[] _class, long L)
70+
{
71+
int n = newOrder.Length;
72+
long[] newClass = new long[n];
73+
newClass[newOrder[0]] = 0;
74+
for (int i = 1; i < n; i++)
75+
{
76+
long cur = newOrder[i];
77+
long prev = newOrder[i - 1];
78+
long mid = (cur + L) % n;
79+
long midPrev = (prev + L) % n;
80+
if (_class[cur] != _class[prev] || _class[mid] != _class[midPrev]) newClass[cur] = newClass[prev] + 1;
81+
else newClass[cur] = newClass[prev];
82+
}
83+
return newClass;
84+
}
85+
}
86+
87+
88+
}

0 commit comments

Comments
 (0)