Commit 33b5f893 authored by Ari Trachtenberg's avatar Ari Trachtenberg
Browse files

Working version.

parent 87c414de
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
package edu.bu.ec504.hw1p3;

import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
@@ -8,7 +7,7 @@ import java.util.ArrayList;
/**
 * A simple implementation of the {@link Compressor} class.
 * This implementation ignores the dictionary entirely, and simply encodes each character of
 * the input as a trivial {@link Compressor.Dictionary.Atom}, indexed against the empty string.
 * the input as a trivial {@link Compressor.Atom}, indexed against the empty string.
 */
public class CharByCharCompressor extends Compressor {

+36 −25
Original line number Diff line number Diff line
package edu.bu.ec504.hw1p3;

import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom;
import java.io.BufferedReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public abstract class Compressor implements Serializable {

  // nested classes
  /**
   * A dictionary to be used in compression.
   */
  static class Dictionary {
    /**
     * An immutable atom of compression that incorporates:
     * a.  An integer representing an index into the dictionary {@link Dictionary#dict}
     * a.  An integer representing an index into some dictionary.
     * b.  A string that follows the dictionary word in a.
     */
     static final class Atom implements Serializable {

      public Atom(int myIndex, String myNext) { index = myIndex; next = myNext; }
      public int getIndex() { return index; }
      public String getNext() { return next; }
      public Atom(int myIndex, String myNext) {
        index = myIndex;
        next = myNext;
      }

      private static final long serialVersionUID = 2L; // for serliazation
      private final int index;
      private final String next;
      public int getIndex() {
        return index;
      }

    Dictionary() {
      dict = new ArrayList<>();
      public String getNext() {
        return next;
      }
    final ArrayList<String> dict;

        /**
         * Pretty print the atom.
         * @return A human-readable string representing this atom.
         */
        @Override
        public String toString() {
            return "Atom{" + "index=" + index + ", next='" + next + '\'' + '}';
        }

        private static final long serialVersionUID = 2L; // for serialization
      private final int index;
      private final String next;
    }

  /**
   * An encapsulation of a list of Atoms.
   */
  public static class CompressedText implements Serializable {
    CompressedText(ArrayList<Atom> theData) {
    CompressedText(List<Atom> theData) {
      data=theData;
    }

    ArrayList<Atom> getList() { return data; }
    private ArrayList<Atom> data;
    private static final long serialVersionUID = 3L; // for serliazation
    List<Atom> getList() { return data; }
    private final List<Atom> data;
    private static final long serialVersionUID = 3L; // for serialization
  }


@@ -49,7 +61,6 @@ public abstract class Compressor implements Serializable {
  // CONSTRUCTORS
  Compressor() { }


  /**
   * Process additional plaintext from <code>in</code> and incorporates it into this compressed object.
   * @param in A BufferedReader linked to an input source.
@@ -61,10 +72,9 @@ public abstract class Compressor implements Serializable {
   * @return The uncompressed text corresponding to this object.
   */
  final public String uncompress(CompressedText theCompressedText) {
    final ArrayList<String> dict = new ArrayList<>();  // a dictionary to be used in compression.
    dict.add(""); // starting point
    final ArrayList<String> dict = emptyDict;  // a dictionary to be used in compression.

    StringBuilder result=new StringBuilder("");
    StringBuilder result=new StringBuilder();
    for (Atom anAtom: theCompressedText.getList()) {
      String nextStr=dict.get( anAtom.getIndex() ) + anAtom.getNext(); // the next String decoded from the theCompressedText
      result.append(nextStr);
@@ -75,5 +85,6 @@ public abstract class Compressor implements Serializable {

  // FIELDS
  private static final long serialVersionUID = 1L; // to allow serialization
  protected static final ArrayList<String> emptyDict = new ArrayList<>(Collections.singletonList("")); // contains just one string, the empty string

}
+42 −0
Original line number Diff line number Diff line
package edu.bu.ec504.hw1p3;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;

/**
 * A slightly more complicated example of a compressor.
 */
public class LineByLineCompressor extends Compressor {
    /**
     * @inheritDoc
     */
    @Override
    public CompressedText processPlainText(BufferedReader in) {
        ArrayList<String> dict = emptyDict;
        ArrayList<Atom> result = new ArrayList<>();

        try {
            for (String line = in.readLine(); line!= null; line = in.readLine()) {
                // find a prefix in the dictionary
                Integer matchingLine=null;        // the last line where a matching prefix was found
                for (int ii=0; ii<dict.size(); ii++)
                    if (line.startsWith(dict.get(ii))) // i.e. dict[ii] is a prefix of line
                        matchingLine=ii;
                if (matchingLine!=null)
                    result.add(new Atom(
                            matchingLine,                                   // add the atom referencing the matching prefix
                            line.substring(dict.get(matchingLine).length()) // followed by everything past the matching prefix
                    ));
                else  // no prefix found, just throw in the entire atom, referencing the empty string
                    result.add( new Atom(0, line));

                dict.add(line);                          // add to the dictionary; the entries have to match the uncompressor's inferred dictionary entries
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new CompressedText(result);               // encapsulate the result
    }
}
+3 −15
Original line number Diff line number Diff line
package edu.bu.ec504.hw1p3;

import edu.bu.ec504.hw1p3.Compressor.CompressedText;
import edu.bu.ec504.hw1p3.Compressor.Dictionary.Atom;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;

import java.io.*;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;

public class Tester {
    // CONSTANTS
@@ -25,7 +14,7 @@ public class Tester {
    // MAIN method
    public static void main(String[] args) {
        try {
            testResult result = testUrl(URLExample, new CharByCharCompressor()); // change this to myCompressor() to test your own compressor
            testResult result = testUrl(URLExample, new LineByLineCompressor()); // change this to myCompressor() to test your own compressor

            System.out.println("Statistics:" + "\n"
                + "   Original size:   " + result.originalSize + "\n"
@@ -68,7 +57,6 @@ public class Tester {
        URL uu = new URL(inURL);
        ReadableByteChannel rbc = Channels.newChannel(uu.openStream());
        FileOutputStream fos = new FileOutputStream(plainFile);
        FileChannel fcl = fos.getChannel();
        fos.getChannel().transferFrom(rbc,0,Long.MAX_VALUE);
        // ... record the file size
        theFile = new File(plainFile);