Skip to content

Commit 6402d43

Browse files
committed
BW transform
1 parent 9bd67cf commit 6402d43

File tree

1 file changed

+55
-26
lines changed

1 file changed

+55
-26
lines changed

week6/src/BurrowsWheeler.java

+55-26
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import edu.princeton.cs.algs4.*;
22

3+
import java.util.ArrayList;
4+
35
public class BurrowsWheeler {
6+
private static final int R = 256; // extended ASCII
47
// apply Burrows-Wheeler transform, reading from standard input and writing to standard output
58
public static void transform(){
69
/*
@@ -19,40 +22,66 @@ public static void transform(){
1922
BinaryStdOut.close();
2023
}
2124

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.
2327
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-
*/
3228
int first = BinaryStdIn.readInt();
3329
String t = BinaryStdIn.readString();
3430

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
3833

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';
4154

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+
}
4467

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+
}
4882

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());
5685
}
5786

5887
// if args[0] is '-', apply Burrows-Wheeler transform

0 commit comments

Comments
 (0)