package homework6;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintStream;
import java.net.MalformedURLException;
import java.util.BitSet;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileNameExtensionFilter;
import homework.huffman;
public class Huffman {
private static class HuffmanComparator implements Comparator{
public int compare(HNODE node1,HNODE node2) {
return node1.freq - node2.freq;
}
}
public Huffman() {};
//파일의 존재유무 및 변환가능 파일인지 확인 후 메세지요청
public static void compresss(String input) throws FileNotFoundException, IOException{
if(input == null) {
throw new NullPointerException("파일을 넣지 않았습니다.");
}
if(input.length()==0) {
throw new IllegalArgumentException("UTF-16으로 인코딩할 수 없습니다.");
}
String Put_Path = null;
String File_name = null;
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("cmp",".cmp","CMP");
chooser.setFileFilter(filter);
int retrival = chooser.showSaveDialog(null);
if(retrival == JFileChooser.APPROVE_OPTION) {
System.out.println(chooser.getCurrentDirectory().toString());
Put_Path =chooser.getCurrentDirectory().toString();
File_name = chooser.getSelectedFile().getName();
System.out.println(File_name);
}else {
System.out.println("파일을 찾을 수 없습니다.");
}
}
final Map charFreq = getCharFrequency(input);
final HNODE root = buildTree(charFreq);
final Map charCode = CodeGenerator(charFreq.keySet(),root);
final String encoded_input = encodeInput(charCode,input);
//숫자와 글자를 연산처리하는 곳.
private static Map getCharFrequency(String input){
final Map map = new HashMap();
for(int i=0;i<input.length();i++) {
char ch = input.charAt(i);if(map.containsKey(ch)) {
int val = map.get(ch);
map.put(ch,++val);
}
else {
map.put(ch, 1);
}
}
return map;
}
private static HNODE buildTree(Mapmap) {
final Queue Priority_Queue = createPrioQueue(map);
while(Priority_Queue.size()>1) {
final HNODE node1 = Priority_Queue.remove();
final HNODE node2 = Priority_Queue.remove();
HNODE node = new HNODE('\0',node1.freq +node2.freq,node1,node2);
Priority_Queue.add(node);
}
return Priority_Queue.remove();
}
//HNODE를 처음으로 돌리는 곳.
private static Queue createPrioQueue(Map map){
final Queue P_Q = new PriorityQueue(10, new HuffmanComparator());
for(Entry entry : map.entrySet()){
P_Q.add(new HNODE(entry.getKey(),entry.getValue(),null,null));
}
return P_Q;
}
//문자를 허프만 코드로 변경하는 부분
private static void Generator(HNODE node,Map map,String s) {
if(node.left == null && node.right == null) {
map.put(node.ch, s);
return;
}
//각 글자를 0과 1로 변환함
Generator(node.left, map, s+'0');
Generator(node.right, map, s+'1');
}
//인코딩할 때 맵의 값을 불러오는 부분
private static String encodeInput(Map charCode,String input) {
final StringBuilder S_B = new StringBuilder();
for(int i=0;i<input.length();i++) {
S_B.append(charCode.get(input.charAt(i)));}
return S_B.toString();
}
private static void serializeTree(HNODE node,String Put_Path,String File_name) throws FileNotFoundException,IOException{
final BitSet bitset = new BitSet();
try(ObjectOutputStream oops_Tree = new ObjectOutputStream(new FileOutputStream(Put_Path+"/"+"tree")))
{
try(ObjectOutputStream oops_Char = new ObjectOutputStream(new FileOutputStream(Put_Path+"/"+"char")))
{
IntObject o = new IntObject();
preOrder(node,oops_Char,bitset,o);
bitset.set(o.bitPosition,true);
oops_Tree.writeObject(bitset);
}
}
}
private static class IntObject{
int bitPosition;
}
//
private static void preOrder(HNODE node,ObjectOutputStream oopsChar,BitSet bitset,IntObject intobject) throws IOException{
if(node.left == null&&node.right == null) {
bitset.set(intobject.bitPosition++,false);
oopsChar.writeChar(node.ch);
return;
}
bitset.set(intobject.bitPosition++,true);
preOrder(node.left, oopsChar, bitset, intobject);
bitset.set(intobject.bitPosition++, true);
preOrder(node.right, oopsChar, bitset, intobject);
}
private static void serializeInput(String message,String Put_path,String File_name) throws IOException {
final BitSet bitset = getBitSet(message);
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(Put_path+"/" + File_name+".cmp"))){
oos.writeObject(bitset);
}
}
private static BitSet getBitSet(String message){
final BitSet bitset = new BitSet();
int i=0;
for(i=0;i
{
if(message.charAt(i)=='1')
{
bitset.set(i,true);
}
else
{
bitset.set(i,false);
}
}
//this will show the end
bitset.set(i,true);
return bitset;
}
private static void expand(String File_dir,String File_name)throws FileNotFoundException,ClassNotFoundException,IOException{
final HNODE root = deserializeTree(File_dir);
decodeMessage(root, File_dir+"/"+File_name);
}
private static HNODE deserializeTree(String File_url) throws FileNotFoundException, IOException, ClassNotFoundException {
try (ObjectInputStream oisBranch = new ObjectInputStream(new FileInputStream(File_url+"/"+"tree"))) {
try (ObjectInputStream oisChar = new ObjectInputStream(new FileInputStream(File_url+"/"+"char"))) {
final BitSet bitSet = (BitSet) oisBranch.readObject();
return preOrder(bitSet, oisChar, new IntObject());
}
}
}
private static HNODE preOrder(BitSet bitSet, ObjectInputStream osChar, IntObject o)throws IOException{
final HNODE node = new HNODE('\0', 0, null, null);
if(!bitSet.get(o.bitPosition)) {
o.bitPosition++;
node.ch = osChar.readChar();
return node;
}
o.bitPosition = o.bitPosition+1;
node.left = preOrder(bitSet, osChar, o);
o.bitPosition = o.bitPosition+1;
node.right = preOrder(bitSet, osChar, o);
return node;
}
private static void decodeMessage(HNODE node, String File_url) throws FileNotFoundException, IOException, ClassNotFoundException{
try(ObjectInputStream ois = new ObjectInputStream(new FileInputStream(File_url))){
final BitSet bitSet = (BitSet) ois.readObject();
final StringBuilder stringBuilder = new StringBuilder();
for(int i=0;i<(bitSet.length()-1);) {
HNODE temp = node;
while(temp.left != null) {
if(!bitSet.get(i)) {
temp = temp.left;
}
else {
temp = temp.right;
}
i = i+1;
}
stringBuilder.append(temp.ch);
}
String Put_Path = null;
String File_name = null;
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("TEXT FILES","txt","text");
chooser.setFileFilter(filter);
int retrival = chooser.showSaveDialog(null);
if(retrival == JFileChooser.APPROVE_OPTION) {
System.out.println(chooser.getCurrentDirectory().toString());
Put_Path = chooser.getCurrentDirectory().toString();
System.out.println(File_name);
}
else {
System.out.println("파일이 선택되지 않았습니다.");
}
try(PrintStream out = new PrintStream(new FileOutputStream(Put_Path+"/"+File_name+".txt"))){
out.print(stringBuilder.toString());
}
}
}
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException,MalformedURLException {
Image image = new ImageIcon("res/zip.png").getImage();
Font font1 = new Font("Arial", Font.PLAIN, 25);
JFrame frame = new JFrame ("허프만 Zip");
frame.setSize(800, 250);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new GridLayout(2,1));
JButton compress_btn = null;
JButton decompress_btn = null;
compress_btn = new JButton("파일압축");
compress_btn.setBackground(Color.GREEN);
compress_btn.setFont(font1);
decompress_btn = new JButton("파일압축해제");
decompress_btn.setBackground(Color.GRAY);
decompress_btn.setFont(font1);
frame.add(compress_btn);
frame.add(decompress_btn);
frame.setIconImage(image);
frame.setVisible(true);
compress_btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
//browse file to compress
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("TEXT FILES", "txt", "text");
chooser.setFileFilter(filter);
chooser.setCurrentDirectory(new java.io.File("."));
chooser.setDialogTitle("파일선택하기");
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
File phile = null;
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
phile = chooser.getSelectedFile();
} else {
System.out.println("파일이 선택되지 않았습니다.");
}
String content = null;
try {
content = new Scanner(phile).useDelimiter("\\Z").next();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
huffman.compress(content);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
decompress_btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter("cmp",".cmp","CMP");
chooser.setFileFilter(filter);
chooser.setCurrentDirectory(new java.io.File("."));
chooser.setDialogTitle("압축을 해제하였습니다.");
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
chooser.setAcceptAllFileFilterUsed(false);
File phile = null;
if (chooser.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
System.out.println(chooser.getCurrentDirectory());
phile = chooser.getSelectedFile();
} else {
System.out.println("파일이 선택되지 않았습니다.");
}
try {
huffman.expand(chooser.getCurrentDirectory().toString(),phile.getName());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
기본적으로 이정도는 짜자 애들아.
중간 똑짤렸노 시바
?
"땔" - dc App
그냥 자바로 허프만 짯다고 올려라
디시에 복붙좀 그만해라