Skip to content
This repository was archived by the owner on Aug 23, 2022. It is now read-only.

Commit

Permalink
fixed a bug, which caused decoded message to have extra-symbols in it…
Browse files Browse the repository at this point in the history
…s end
  • Loading branch information
Anssi Kinnunen committed Mar 8, 2013
1 parent 9c344d8 commit 81cedd7
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 28 deletions.
26 changes: 15 additions & 11 deletions src/main/java/bluemoon/Huffman/Decoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
*/
public class Decoder {

private static int encodedMsgLength = 0;

public Decoder() {

}
Expand All @@ -20,7 +22,7 @@ public Decoder() {
* Decodes the contents of given (binary encoded) file. Utilizes a lookUp-table provided by
* Encoder-class.
*
* @param lookUpFile
* @param lookUpFile LookUp-table for decoder.
*/
public void decode(File lookUpFile, boolean debug) {
String rawLookUpMsg = readFromLookupFile();
Expand All @@ -39,7 +41,6 @@ public void decode(File lookUpFile, boolean debug) {
/**
* Reads data from a pre-determined lookUp-table and returns it as a String.
*
* @param lookupFile File, where the lookUp-table for decodable message resides.
* @return Raw data from the lookUp-table as a String.
*/
public String readFromLookupFile() {
Expand All @@ -49,18 +50,16 @@ public String readFromLookupFile() {
System.exit(0);
}
BufferedReader bufReader;
StringBuilder sbBuilder = new StringBuilder();
String auxLine = "";
String line = "";
try {
bufReader = new BufferedReader(new FileReader(lookUpFile));
while ((auxLine = bufReader.readLine()) != null) {
sbBuilder.append(auxLine);
}
line = bufReader.readLine();
encodedMsgLength = Integer.parseInt(bufReader.readLine());
bufReader.close();
} catch (IOException ie) {
ie.printStackTrace();
}
return sbBuilder.toString();
return line;
}

/**
Expand Down Expand Up @@ -92,7 +91,7 @@ public String parseLookupMsg(String lookUpMsg, String msgRegex,
* Rebuilds the Huffman-tree from the given message.
*
* @param message Message as a String.
* @return Huffman-tree as ArrayList< Node >.
* @return Huffman-tree as ArrayList<Node>.
*/
public ArrayList<Node> rebuildHuffmanTree(String message) {
SortedMap<String, Integer> weightedList = TreeBuilder
Expand All @@ -108,7 +107,7 @@ public ArrayList<Node> rebuildHuffmanTree(String message) {
* by traversing the Huffman-tree as the original algorithm suggests. This type of decoding, however, is
* painfully slow and is practically unusable for any text files over 30KB in size.
*
* @param huffmanTree Huffman-tree as ArrayList< Node >.
* @param huffmanTree Huffman-tree as ArrayList<Node>.
* @return Decoded message as a String.
*/
public String decodeMessage(ArrayList<Node> huffmanTree) {
Expand All @@ -120,13 +119,18 @@ public String decodeMessage(ArrayList<Node> huffmanTree) {

// Reads binary input and creates string encoded message accordingly, adding
// "1" or "0" to the string
// binaryEncodedMsg.length
int auxCalculator = encodedMsgLength;
for (int i = 0; i < binaryEncodedMsg.length; i++) {
for (int j = 7; j >= 0; j--) {
if (((binaryEncodedMsg[i] >> j) & 1) == 1) {
if (auxCalculator == 0) {
break;
} else if (((binaryEncodedMsg[i] >> j) & 1) == 1) {
stringEncodedMsg.append("1");
} else {
stringEncodedMsg.append("0");
}
auxCalculator -= 1;
}
}
// Bit-by-bit-decoding method, "by the book". Painfully slow method for anything useful.
Expand Down
9 changes: 5 additions & 4 deletions src/main/java/bluemoon/Huffman/Encoder.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void encode(File file, boolean debug) {
*
* @param message Message to be encoded as a String.
* @param debug If set to true, function will print out the weighted list.
* @return Huffman-tree as ArrayList< Node >.
* @return Huffman-tree as ArrayList<Node>.
*/
public ArrayList<Node> buildHuffmanTree(String message, boolean debug) {
weightedList = TreeBuilder.createWeightedList(message);
Expand All @@ -62,7 +62,7 @@ public ArrayList<Node> buildHuffmanTree(String message, boolean debug) {
/**
* Builds true binary encoded message into Byte[].
*
* @param huffmanTree Huffman-tree as ArrayList< Node >.
* @param huffmanTree Huffman-tree as ArrayList<Node>.
* @param message Message to be encoded as String.
* @param debug If set to true, function will print out code list.
* @return Binary encoded message as Byte[].
Expand Down Expand Up @@ -119,7 +119,7 @@ public void writeBinaryToFile(byte[] binaryEncodedMsg) {
* BRP == pair separator (eg. symbol 'a' and related weight 10 would be aBRP10, as in "a 'BRP' 10")
* BRL == pairs separator (eg. multiple pairs separated by BRL would be aBPR10BRLcBRP5 etc.)
*
* @param weightedList Weighted list as SortedMap< String, Integer >.
* @param weightedList Weighted list as SortedMap<String, Integer>.
*/
public void createLookUpTable(SortedMap<String, Integer> weightedList,
boolean debug) {
Expand All @@ -134,7 +134,8 @@ public void createLookUpTable(SortedMap<String, Integer> weightedList,
}
}
File lookUpFile = new File("testiLookUp.txt");
writeToFile(lookUpFile, lookUpTableContents.toString());
writeToFile(lookUpFile, lookUpTableContents.toString() + "\r\n"
+ encodedMsgLength);
if (debug) {
System.out.println("Created lookUp-table in file "
+ lookUpFile.getAbsolutePath());
Expand Down
26 changes: 13 additions & 13 deletions src/main/java/bluemoon/Huffman/TreeBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@
public class TreeBuilder {

/**
* Attaches according weight to each symbol in a SortedMap< String, Integer >. Weight is the symbol's frequency
* Attaches according weight to each symbol in a SortedMap<String, Integer>. Weight is the symbol's frequency
* in the given message.
*
* @throws IllegalArgumentException Message has to be longer than 1
* @param message String, which contains the message to be encoded.
* @return A weighted list of the type SortedMap< String, Integer >.
* @return A weighted list of the type SortedMap<String, Integer>.
*/
public static SortedMap<String, Integer> createWeightedList(String message) {
if (message.length() < 2) {
Expand All @@ -44,12 +44,12 @@ public static SortedMap<String, Integer> createWeightedList(String message) {
}

/**
* Creates a new node list of type ArrayList< Node > from a weighted list. The node list
* Creates a new node list of type ArrayList<Node> from a weighted list. The node list
* contains an unordered group of nodes without links to their parents and children.
*
* @throws IllegalArgumentException Message has to contain more than one different symbol
* @param weightedList
* @return Node list of type ArrayList< Node >.
* @return Node list of type ArrayList<Node>.
*/
public static ArrayList<Node> createNodeList(
SortedMap<String, Integer> weightedList) {
Expand All @@ -71,11 +71,11 @@ public static ArrayList<Node> createNodeList(
* each iteration, the first two nodes are linked to an empty parent node which has no symbol,
* but which has the combined weight of it's children. Child nodes are removed from the node list and
* the parent node is added back to the nodes list. Nodes, which contain an symbol (also called leaf nodes),
* are also added to the Huffman-tree ArrayList< Node >, which this function returns. Finally the
* are also added to the Huffman-tree ArrayList<Node>, which this function returns. Finally the
* root node is added to the beginning of the Huffman-tree.
*
* @param nodes ArrayList< Node >, which contains >= 2 nodes.
* @return An ordered ArrayList< Node >, which contains the Huffman-tree's root node and all leaf nodes.
* @param nodes ArrayList<Node>, which contains >= 2 nodes.
* @return An ordered ArrayList<Node>, which contains the Huffman-tree's root node and all leaf nodes.
*/
public static ArrayList<Node> createHuffmanTree(ArrayList<Node> nodes) {
ArrayList<Node> huffmanTree = new ArrayList<Node>();
Expand Down Expand Up @@ -121,15 +121,15 @@ public static ArrayList<Node> createHuffmanTree(ArrayList<Node> nodes) {
}
} // endof while
return huffmanTree;
} // endof returnHuffTree
} // endof createHuffmanTree

/**
* Creates code list for the leaf nodes of Huffman-tree. The algorithm iterates the
* tree for each node by traversing from the leaf node to root node, where being left child means
* 0 (zero) and right child means 1 (one), since it's a binary tree. Codes are saved to a SortedMap < String, String >.
* 0 (zero) and right child means 1 (one), since it's a binary tree. Codes are saved to a SortedMap <String, String>.
*
* @param huffmanTree Huffman-tree of the type ArrayList< Node >.
* @return SortedMap A complete code list of type SortedMap < String, String > for the Huffman-tree.
* @param huffmanTree Huffman-tree of the type ArrayList<Node>.
* @return SortedMap A complete code list of type SortedMap <String, String> for the Huffman-tree.
*/
public static SortedMap<String, String> createCodeList(
ArrayList<Node> huffmanTree) {
Expand Down Expand Up @@ -159,7 +159,7 @@ public static SortedMap<String, String> createCodeList(
* Encodes the message into binary-looking String (eg. "1001010"). This can be used for simple
* tree traversal and also decoding.
*
* @param codeList Code list of type SortedMap< String, String >.
* @param codeList Code list of type SortedMap<String, String>.
* @param message The message we want to encode in a String.
* @return Encoded string that looks like binary.
*/
Expand All @@ -181,7 +181,7 @@ public static String createStringEncodedMsg(
* "binary-string's" length. We then iterate the byte array, shifting the bits in each byte according to
* the binary-string to determine if the bit is 0 or 1.
*
* @param codeList Code list of type SortedMap< String, String >.
* @param codeList Code list of type SortedMap<String, String>.
* @param stringEncodedMsg String, which contains message encoded into "string-binary" (eg. "1001010").
* @return Message encoded into true binary of type Byte[].
*/
Expand Down

0 comments on commit 81cedd7

Please sign in to comment.