1
1
import edu .princeton .cs .algs4 .*;
2
2
3
+ import java .util .ArrayList ;
4
+
3
5
public class BurrowsWheeler {
6
+ private static final int R = 256 ; // extended ASCII
4
7
// apply Burrows-Wheeler transform, reading from standard input and writing to standard output
5
8
public static void transform (){
6
9
/*
@@ -19,40 +22,66 @@ public static void transform(){
19
22
BinaryStdOut .close ();
20
23
}
21
24
22
- // apply Burrows-Wheeler inverse transform, reading from standard input and writing to standard output
25
+ // Apply Burrows-Wheeler inverse transform, reading from standard input and writing to standard output.
26
+ // Must be proportional to n + R (or better) in the worst case.
23
27
public static void inverseTransform (){
24
- /*
25
- must be proportional to n + R (or better) in the worst case
26
- 3 - first
27
- ARD!RCAAAABB - sorted
28
- !
29
-
30
- 1. next[] - redefined. Then used to reconstruct the original array.
31
- */
32
28
int first = BinaryStdIn .readInt ();
33
29
String t = BinaryStdIn .readString ();
34
30
35
- String firstCol = null ; // TODO
36
- // Generates next array used to invert to the original
37
- // gets next[] - array where next[i] == i+1, where i index of original suffix
31
+ // 1. generate `next` array used to invert to the original
32
+ // next[] - array where next[i] == i+1, where i index of original suffix
38
33
39
- // sort using Bucket Sort ; O(n) space / time
40
- // but how to get source inx? make it int[int[]] ? int[char] - gets array of source indexes?
34
+ // 1.1 get first col as indexes of last col:
35
+ // sort using Counting Sort ; O(n) space / time
36
+ ArrayList <ArrayList <Integer >> firstColCharGroups = new ArrayList <ArrayList <Integer >>(R );
37
+ for (int c = 0 ; c < R ; c ++) firstColCharGroups .add (new ArrayList <Integer >());
38
+ for (int i = 0 ; i < t .length (); i ++)
39
+ firstColCharGroups .get (t .charAt (i )).add (i );
40
+ // get number of chars before a group of chars (base):
41
+ int [] firstColGroupBases = new int [R ];
42
+ firstColGroupBases [0 ] = 0 ;
43
+ StringBuilder firstCol = new StringBuilder (t .length ());
44
+ firstCol .setLength (t .length ());
45
+ for (int i = 1 ; i < R ; i ++)
46
+ {
47
+ int base = firstColCharGroups .get (i - 1 ).size () + firstColGroupBases [i - 1 ];
48
+ firstColGroupBases [i ] = base ;
49
+ ArrayList <Integer > group = firstColCharGroups .get (i );
50
+ for (int j = 0 ; j < group .size (); j ++)
51
+ firstCol .setCharAt (base + j , t .charAt (group .get (j )));
52
+ }
53
+ assert firstCol .charAt ((int )firstCol .length ()/2 ) != '\u0000' ;
41
54
42
- int [] next = new int []; // TODO
43
- // for each group of chars determine next[]; O(n) space / time
55
+ // 1.2 from sorted chars depict `next`
56
+ int [] next = new int [t .length ()];
57
+ for (int c = 0 ; c < R ; c ++)
58
+ {
59
+ int base = firstColGroupBases [c ];
60
+ ArrayList <Integer > indexes = firstColCharGroups .get (c );
61
+ for (int i = 0 ; i < indexes .size (); i ++) {
62
+ int firstColCharInx = base + i ;
63
+ int lastColCharInx = indexes .get (i );
64
+ next [firstColCharInx ] = lastColCharInx ;
65
+ }
66
+ }
44
67
45
- String original = invertMessage (next , first , firstCol , t );
46
- BinaryStdOut .write (original );
47
- }
68
+ // 2. invert, generate original string
69
+ // given sorted first column
70
+ // first char in output is at `first`
71
+ // next char in output is at next[first]
72
+ // .. so on
73
+ StringBuilder original = new StringBuilder ();
74
+ original .setLength (t .length ());
75
+ int next_i = first ;
76
+ for (int i = 0 ; i < t .length (); i ++)
77
+ {
78
+ char ch = firstCol .charAt (next_i );
79
+ original .setCharAt (i , ch );
80
+ next_i = next [next_i ];
81
+ }
48
82
49
- // generate original string
50
- private static String invertMessage (int [] next , int first , String firstCol , String lastCol ) {
51
- // given sorted first column
52
- // first char in output is at first
53
- // next char in output is at next[first]
54
- // .. so on
55
- return null ;
83
+ System .out .print (original .toString ());
84
+ //BinaryStdOut.write(original.toString());
56
85
}
57
86
58
87
// if args[0] is '-', apply Burrows-Wheeler transform
0 commit comments