From 751ca898931c69a871c3a6b9d17bdabbe84b5fec Mon Sep 17 00:00:00 2001 From: MicahGold <89551291+MicahGold@users.noreply.github.com> Date: Thu, 23 Sep 2021 11:11:17 -0700 Subject: [PATCH 1/2] Final Compile Comments added when needed. Removed System.out.print lines to increase efficiency Decreased Big O of encode method and increased functionality of encode Added a timer in ms --- .project | 11 ++++++ LZW Compression/src/LZWObject.java | 51 ++++++++++++++++------------ LZW Compression/src/decompressed.txt | 0 LZW Compression/src/output.txt | 1 + 4 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 .project create mode 100644 LZW Compression/src/decompressed.txt create mode 100644 LZW Compression/src/output.txt diff --git a/.project b/.project new file mode 100644 index 0000000..9869ee8 --- /dev/null +++ b/.project @@ -0,0 +1,11 @@ + + + LZW-Compression + + + + + + + + diff --git a/LZW Compression/src/LZWObject.java b/LZW Compression/src/LZWObject.java index 32e2ac9..c36123e 100644 --- a/LZW Compression/src/LZWObject.java +++ b/LZW Compression/src/LZWObject.java @@ -30,7 +30,9 @@ public LZWObject( File message) { super(); this.message = message; } + // encodes message as a byteArray and outputs said byte array to output.txt public static void encode() throws IOException { + final long startTime = System.currentTimeMillis(); dictionary = new HashMap(); FileReader reader = new FileReader(message); String current = "" + (char)reader.read(); @@ -44,7 +46,7 @@ public static void encode() throws IOException { while (reader.ready()) { if (!dictionary.containsKey(current + next)) { dictionary.put(current + next, codeOn); - nums.add(codeOn); + nums.add(dictionary.get(current)); codeOn++; current = next; next = "" + (char)reader.read(); @@ -59,19 +61,20 @@ public static void encode() throws IOException { byte[] bitArray = stringToBinary(stringBits); FileOutputStream output = new FileOutputStream(new File ("output.txt")); output.write(bitArray); + System.out.print(System.currentTimeMillis() - startTime); output.close(); } - + // converts a number to a binary string with len number of digits private static String toBinary(int x, int len) { if (len > 0) { - return String.format("%" + len + "s", - Integer.toBinaryString(x)).replaceAll(" ", "0"); + return String.format("%" + len + "s", Integer.toBinaryString(x)).replaceAll(" ", "0"); } return null; } + // converts an ArrayList of ints to a String composed of the 9 bit binary representation of each of those ints private static String allToBinary(ArrayList ints) { StringBuilder str = new StringBuilder(); for (int num : ints) { @@ -79,24 +82,30 @@ private static String allToBinary(ArrayList ints) { } return str.toString(); } + // converts a string representation of binary values to a byte array + // puts extra 0's at the end of the String to ensure that it can be stored in a byte array (multiple of 8 bits) private static byte[] stringToBinary(String str) { - while(str.length()%8 !=0) + int zeroes = (str.length() %8); + if (zeroes != 0) { - str += 0; + String zero = "0000000"; + str += zero.substring(0, 8 - zeroes); } + byte[] bytes = new byte[str.length()/8]; int counter = 0; for (int i = 0; i < str.length(); i+= 8) { bytes[counter] = (byte)Integer.parseInt(str.substring(i, i+8), 2); - System.out.println(bytes[counter]); counter++; } return bytes; } + // takes in a text file of binary and deciphers the binary + // reverses the operations of encode, outputing the original message to a text file public void decode(String filename, int bitSize) throws IOException { - - reinitializeDictionary(); + final long startTime = System.currentTimeMillis(); + initializeDecoderDictionary(); String masterString = readFromCompressedFile(filename, bitSize); int [] integerValues = convertStringToIntegers(masterString, bitSize); rebuildDictionary(integerValues); @@ -112,10 +121,12 @@ public void decode(String filename, int bitSize) throws IOException output.write(("" + decoderDictionary.get(integerValues[i])).replaceAll("null", "@")); } } + System.out.print(System.currentTimeMillis() - startTime); } - public void reinitializeDictionary() + // initializes decoderDictionary with ASCII + public void initializeDecoderDictionary() { decoderDictionary = new HashMap(); for(int i = 0; i < 256; i++) @@ -123,20 +134,21 @@ public void reinitializeDictionary() decoderDictionary.put(i, "" + (char) i); } } - + // reads the file created by encode and returns a String of appended binary values public String readFromCompressedFile(String filename, int bitSize) throws IOException { - FileReader reader = new FileReader(filename); - String decoderMasterString = ""; + FileReader reader = new FileReader(filename); + String decoderMasterString = ""; int character; BufferedReader br = new BufferedReader(reader); while ((character = br.read()) != -1) { - decoderMasterString += toBinary(character, 8); + decoderMasterString += toBinary(character, 8); } decoderMasterString = decoderMasterString.substring(0, decoderMasterString.length() - decoderMasterString.length()%bitSize); return decoderMasterString; } + // converts a given binary to string to an integer representation and returns that int public int [] convertStringToIntegers(String binValueString, int bitSize) { int [] encodedValueArray = new int [binValueString.length()/bitSize]; @@ -144,19 +156,20 @@ public String readFromCompressedFile(String filename, int bitSize) throws IOExce for(int i = 0; i < binValueString.length() - bitSize; i += bitSize) { encodedValueArray[counter] = Integer.parseInt(binValueString.substring(i, i + bitSize),2); - System.out.println(encodedValueArray[counter]); counter++; } return encodedValueArray; } + + // loops through array of integers representing Strings in the encoder dictionary + // adds LZW combined ASCII values to the decoderDictionary to make it emthe encoder dict public void rebuildDictionary(int [] numberEntries) { String c = ""; for(int i = 0; i < numberEntries.length; i++) { String cn = (c + decoderDictionary.get(numberEntries[i])).replaceAll("null", "@"); - System.out.println(cn); if(decoderDictionary.containsValue(cn)) { c = cn; @@ -167,14 +180,10 @@ public void rebuildDictionary(int [] numberEntries) c = cn.substring(cn.length()-1); } } - for(int i = 0; i < numberEntries.length; i++) - { - System.out.println(numberEntries[i]); - } } public static void main (String [] args) throws IOException { - LZWObject obj = new LZWObject(new File("lzw-file1.txt")); + LZWObject obj = new LZWObject(new File("lzw-file2.txt")); obj.encode(); obj.decode("output.txt", 9); } diff --git a/LZW Compression/src/decompressed.txt b/LZW Compression/src/decompressed.txt new file mode 100644 index 0000000..e69de29 diff --git a/LZW Compression/src/output.txt b/LZW Compression/src/output.txt new file mode 100644 index 0000000..185730f --- /dev/null +++ b/LZW Compression/src/output.txt @@ -0,0 +1 @@ +0˜Œp‚ ¨<. ‡Ã¢0ØœB)ŠÆ"ñ¨´r3Ǥ2ÙÊf3È£ò©L²Fc’Éå²¹tÊk4›Ìç3iÔâw>žÐ'”)ýƒD£Ñ©4ZX \ No newline at end of file From 185c94f208dfcf485012cb135e035017b34e9687 Mon Sep 17 00:00:00 2001 From: MicahGold <89551291+MicahGold@users.noreply.github.com> Date: Thu, 23 Sep 2021 11:29:31 -0700 Subject: [PATCH 2/2] Updated README to Reflect Final Product tldr unbeatable variable names maintained --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4a57079..e1bc9d4 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,14 @@ # LZW-Compression -The algorithm is slightly broken but the handling of the dictionary into binary is optimized properly – 9 bits are stored by 9 bits, not 2 bytes (16 bits); the algorithm needs to be touched up to store traditional ascii characters before doing other things so look out for that. If you fix the algorithm, the conversion into binary will still function properly. +From a functionality perspective: +The encode method has been improved from prior versions although it is still not ideal -- before the encode method did not encode the current value and instead +added the dictionary value (256,257 . . . ) sequentially. Now it at least correctly encodes the current value (edge cases have not been tested). +The decode method appears to be functioning correctly. -https://www.youtube.com/watch?v=iik25wqIuFo watch this for specific information – instructional video on how to make algorithm. I commented on the bottom to explain what was wrong with mine. +From a big O perspective: +A for loop has been eliminated in the encdoe method which caused a decrease in run time from 11587 ---> 45 overall. +Some of this decrease can be attributed to eliminating System.out.println methods that were used by the initial coder to test the code +System.out.println have also been removed from the decode method decreasing the runtime from 4298 --> 14 overalll + +From a code clarity persepctive: at least 1 method was renamed to more accurately reflect what the method accomplishes. +I tried very hard to maintain Louis and Tyler's stylistic variable names and method names --- comments were used to explain methods that were oddly named +or carried out numerous operations at the same time.