编写一个压缩软件(Java实现版本)

题目3.编写一个压缩软件

内容:

编写一个压缩软件,选择两种压缩算法(自选),将用户提交的文件实现压缩并提示用户压缩率并提示用户按压缩率高的算法压缩;该软件还可通过文件格式识别文件是否是本软件压缩并按压缩时的算法解压。

教学模式:

理解并分析题目需求,查找资料,设计数据结构和算法,选择最优算法和编程工具。

知识点:

使用多种存储结构,使用两种压缩算法,算法评估

能力:

能够掌握多种存储结构,自学多种压缩算法并选择合理的结构存储数据,选择适当的工具编写程序,掌握算法的评估,编写程序实现题目要求。

介绍:

使用哈夫曼压缩和lzw压缩方法,具体算法请自行百度,此处不做详细介绍。源码请在文末github地址处下载。

截图效果

在这里插入图片描述

部分代码

package function;

import java.io.*;
import java.util.*;

public class LZWCompression {

	/**
	 * Define a HashMap and other variables that will be used in the program
	 */
	public HashMap<String, Integer> table = new HashMap<String, Integer>();
	// public TreeMap<String,Integer> table = new TreeMap<String,Integer>();
	private String[] Array_char;
	private int count;

	/** Default Constructor */
	public LZWCompression() {
	}

	public void LZW_Compress(String input, String output) throws IOException {

		/** Initialize the variables */

		Array_char = new String[4096];
		for (int i = 0; i < 256; i++) {
			table.put(Character.toString((char) i), i);
			Array_char[i] = Character.toString((char) i);
		}
		count = 256;

		/** Pointer to input and output file */
		DataInputStream read = new DataInputStream(new BufferedInputStream(
				new FileInputStream(input)));

		DataOutputStream out = new DataOutputStream(new BufferedOutputStream(
				new FileOutputStream(output)));

		/** Local Variables */
		byte input_byte;
		String temp = "";
		byte[] buffer = new byte[3];
		boolean onleft = true;

		try {

			/** Read the First Character from input file into the String */
			input_byte = read.readByte();
			int i = new Byte(input_byte).intValue();
			if (i < 0) {
				i += 256;
			}
			char c = (char) i;
			temp = "" + c;

			/** Read Character by Character */
			while (true) {
				input_byte = read.readByte();
				i = new Byte(input_byte).intValue();

				if (i < 0) {
					i += 256;
				}
				c = (char) i;

				if (table.containsKey(temp + c)) {
					temp = temp + c;
				} else {
					String s12 = to12bit(table.get(temp));
					/**
					 * Store the 12 bits into an array and then write it to the
					 * output file
					 */

					if (onleft) {
						buffer[0] = (byte) Integer.parseInt(
								s12.substring(0, 8), 2);
						buffer[1] = (byte) Integer.parseInt(
								s12.substring(8, 12) + "0000", 2);
					} else {
						buffer[1] += (byte) Integer.parseInt(
								s12.substring(0, 4), 2);
						buffer[2] = (byte) Integer.parseInt(
								s12.substring(4, 12), 2);
						for (int b = 0; b < buffer.length; b++) {
							out.writeByte(buffer[b]);
							buffer[b] = 0;
						}
					}
					onleft = !onleft;
					if (count < 4096) {
						table.put(temp + c, count++);
					}
					temp = "" + c;
				}
			}

		} catch (EOFException e) {
			String temp_12 = to12bit(table.get(temp));
			if (onleft) {
				buffer[0] = (byte) Integer.parseInt(temp_12.substring(0, 8), 2);
				buffer[1] = (byte) Integer.parseInt(temp_12.substring(8, 12)
						+ "0000", 2);
				out.writeByte(buffer[0]);
				out.writeByte(buffer[1]);
			} else {
				buffer[1] += (byte) Integer
						.parseInt(temp_12.substring(0, 4), 2);
				buffer[2] = (byte) Integer
						.parseInt(temp_12.substring(4, 12), 2);
				for (int b = 0; b < buffer.length; b++) {
					out.writeByte(buffer[b]);
					buffer[b] = 0;
				}
			}
			read.close();
			out.close();
		}

	}

	/** Convert 8 bit to 12 bit */
	public String to12bit(int i) {
		String temp = Integer.toBinaryString(i);
		while (temp.length() < 12) {
			temp = "0" + temp;
		}
		return temp;
	}


	public int getvalue(byte b1, byte b2, boolean onleft) {
		String temp1 = Integer.toBinaryString(b1);
		String temp2 = Integer.toBinaryString(b2);
		while (temp1.length() < 8) {
			temp1 = "0" + temp1;
		}
		if (temp1.length() == 32) {
			temp1 = temp1.substring(24, 32);
		}
		while (temp2.length() < 8) {
			temp2 = "0" + temp2;
		}
		if (temp2.length() == 32) {
			temp2 = temp2.substring(24, 32);
		}

		/** On left being true */
		if (onleft) {
			return Integer.parseInt(temp1 + temp2.substring(0, 4), 2);
		} else {
			return Integer.parseInt(temp1.substring(4, 8) + temp2, 2);
		}

	}


	public void LZW_Decompress(String input, String output) throws IOException {
		/** Initialize the variables */

		Array_char = new String[4096];
		for (int i = 0; i < 256; i++) {
			table.put(Character.toString((char) i), i);
			Array_char[i] = Character.toString((char) i);
		}
		count = 256;

		/** Stream pointer to input and output file path */
		DataInputStream in = new DataInputStream(new BufferedInputStream(
				new FileInputStream(input)));

		DataOutputStream out = new DataOutputStream(new BufferedOutputStream(
				new FileOutputStream(output)));

		int currword, priorword;
		byte[] buffer = new byte[3];
		boolean onleft = true;
		try {

			/**
			 * Get the first word in code and output its corresponding character
			 */
			buffer[0] = in.readByte();
			buffer[1] = in.readByte();

			priorword = getvalue(buffer[0], buffer[1], onleft);
			onleft = !onleft;
			out.writeBytes(Array_char[priorword]);

			/**
			 * Read every 3 bytes and generate a corresponding characters - 2
			 * character
			 */
			while (true) {

				if (onleft) {
					buffer[0] = in.readByte();
					buffer[1] = in.readByte();
					currword = getvalue(buffer[0], buffer[1], onleft);
				} else {
					buffer[2] = in.readByte();
					currword = getvalue(buffer[1], buffer[2], onleft);
				}
				onleft = !onleft;
				if (currword >= count) {

					if (count < 4096)
						Array_char[count] = Array_char[priorword]
								+ Array_char[priorword].charAt(0);
					count++;
					out.writeBytes(Array_char[priorword]
							+ Array_char[priorword].charAt(0));
				} else {

					if (count < 4096)
						Array_char[count] = Array_char[priorword]
								+ Array_char[currword].charAt(0);
					count++;
					out.writeBytes(Array_char[currword]);
				}
				priorword = currword;
			}

		} catch (EOFException e) {
			in.close();
			out.close();
		}
	}
}

源码下载:

完整项目下载:点此获取
或许有帮到你的话可以点个Star么~

猜你喜欢

转载自blog.csdn.net/qq_37221167/article/details/90399495