KS1_2_Projekt/Main.java

427 lines
12 KiB
Java

import java.util.HashMap;
import java.util.*;
import java.nio.ByteBuffer;
import java.util.Stack;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main
{
public static byte[] nullCharBytes = {(byte)0xFF,(byte)0xFF};
//public static String nullCharBytesString = "1111111111111111";
public static void test(String text)
{
Map<Character, Integer> zahlen = Zählen.countEachLetter(text);
Node wurzel = Node.erstellen(zahlen);
System.out.println();
System.out.println("Pre-Order Baum:");
printBaum(wurzel);
System.out.println();
System.out.println("Anzahl der Zeichen:");
Zählen.printZahl(zahlen);
System.out.println();
System.out.println("Binärcode der Zeichen:");
codes(text);
System.out.println();
decodierungBaum(codierung(text,wurzel), wurzel);
System.out.println(byteString_to_character(character_to_byteString(null)));
System.out.println(byteString_to_character(character_to_byteString('b')));
System.out.println(byteString_to_character(character_to_byteString('c')));
System.out.println(byteString_to_character(character_to_byteString('d')));
System.out.println(byteString_to_character(character_to_byteString('e')));
System.out.println(byteString_to_character(character_to_byteString('f')));
System.out.println(byteString_to_character(character_to_byteString('g')));
System.out.println(byteString_to_character(character_to_byteString('h')));
byteString_to_baum(baum_to_byteString(wurzel));
printBaum(wurzel);
}
public static void test2()
{
Map<Character, Integer> zahlen = Zählen.countEachLetter("aaaabbc");
Node wurzel = Node.erstellen(zahlen);
printBaum(wurzel);
//byteString_to_baum(baum_to_byteString(wurzel));
HashMap<Character, String> codes = new HashMap<Character, String>();
if(wurzel.getLeft() == null && wurzel.getRight() == null)
{
codes.put(wurzel.getBuchstabe(), "0");
}
else
{
generieren(codes,wurzel,"");
}
for (var entry : codes.entrySet())
{
System.out.println("->" + entry.getKey() + ", Code: " + entry.getValue());
}
printBaum(byteString_to_baum(baum_to_byteString(wurzel)));
}
public static void test3()
{
System.out.println(decodierungInlkBaum(codierungInklBaum("aaaabbc")));
}
public static void printBaum(Node baum)
{
if(baum == null)return;
System.out.println("Buchstabe: " + baum.getBuchstabe() + ", Anzahl: " + baum.getAnzahl());
printBaum(baum.getLeft());
printBaum(baum.getRight());
}
public static void codes(String text)
{
Node wurzel = Node.erstellen(Zählen.countEachLetter(text));
HashMap<Character, String> codes = new HashMap<Character, String>();
if(wurzel.getLeft() == null && wurzel.getRight() == null)
{
codes.put(wurzel.getBuchstabe(), "0");
}
else
{
generieren(codes,wurzel,"");
}
for (var entry : codes.entrySet())
{
System.out.println("->" + entry.getKey() + ", Code: " + entry.getValue());
}
}
public static void generieren(HashMap<Character, String> codes, Node node, String code)
{
if(node == null)return;
System.out.println(node.getBuchstabe() +" " + code);
if(node.getLeft() == null && node.getRight() == null)
{
codes.put(node.getBuchstabe(), code);
return;
}
generieren(codes, node.getLeft(), code + "0");
generieren(codes, node.getRight(), code + "1");
}
public static String codierung(String text, Node wurzel)
{
HashMap<Character, String> codes = new HashMap<Character, String>();
if(wurzel.getLeft() == null && wurzel.getRight() == null)
{
codes.put(wurzel.getBuchstabe(), "0");
}
else
{
generieren(codes,wurzel,"");
}
String code = "";
for (int i=0; i<text.length();i++)
{
char b = text.charAt(i);
String c = codes.get(b);
code += c;
}
System.out.println("Huffman-Codierung: " + code);
return code;
}
public static String codierungInklBaum(String text)
{
//zahl wan angibt wan text kommt und baum aufhört
//decodiere baum, dcodierung text
Map<Character, Integer> zahlen = Zählen.countEachLetter(text);
Node baum = Node.erstellen(zahlen);
String codierterBaum = baum_to_byteString(baum);
String codierterText = codierung(text,baum);
int textErstIndex = codierterBaum.length() + 32;
String codiertertextErstIndex = Int_to_ByteString(textErstIndex);
System.out.println(codiertertextErstIndex + codierterBaum +" " + codierterText);
return codiertertextErstIndex + codierterBaum + codierterText;
}
public static String decodierungInlkBaum(String code)
{
String codierterTextErstIndex = code.substring(0,32);
int textErstIndex = byteString_to_int(codierterTextErstIndex);
String codierterBaum = code.substring(32, textErstIndex);
Node decodierterBaum = byteString_to_baum(codierterBaum);
String codierterText = code.substring(textErstIndex, code.length());
String decodierterText = decodierungBaum(codierterText,decodierterBaum);
return decodierterText;
}
public static String decodierungBaum(String code,Node baum)
{
Node current = baum;
String decoded = "";
boolean hatNurEinBuchstabenart = current.getRight() == null && current.getLeft() == null;
if(hatNurEinBuchstabenart)
{
for(int i=0;i<code.length();i++)
{
decoded += baum.getBuchstabe();
}
System.out.println(decoded);
return decoded;
}
for(int i =0;i<code.length();i++)
{
if(code.charAt(i) == '1')
{
current= current.getRight();
}
if(code.charAt(i) == '0')
{
current = current.getLeft();
}
if(current.getRight() == null && current.getLeft() == null)
{
decoded += current.getBuchstabe();
current = baum;
}
}
System.out.println(decoded);
return decoded;
}
public static Byte ByteString_to_Byte (String byteString)
{
if(byteString.length() != 8)
{
System.out.println(">8");
return null;
}
byte result = 0;
for(byte i=0 ;i<8;i++)
{
if(byteString.charAt(7-i) == '1')result|=1<<i; //verschiebt die 1 um i binärpositionen nach links
else if(byteString.charAt(7-i) != '0')
{
System.out.println("was flasch");
return null;
}
}
return result;
}
public static String Byte_to_ByteString (byte b)
{
String result = "";
for(byte i=0;i<8;i++)
{
boolean bit= ((b>>(7-i))&1)==1;
result+= bit?'1': '0'; //falls bit wert 1 hat addiert es 1 zu dem string, wenn nicht dann addiertes es 0
}
return result;
}
public static String character_to_byteString (Character c)
{
byte[] b = nullCharBytes;
if(c != null)
{
var byteBuffer = ByteBuffer.allocate(2);
byteBuffer.putChar(c);
b = byteBuffer.array();
}
String result = "";
for(int i=0;i<b.length;i++)
{
result += Byte_to_ByteString(b[i]);
}
return result;
}
public static Character byteString_to_character (String byteString)
{
byte a = ByteString_to_Byte(byteString.substring(0,8));
byte b = ByteString_to_Byte(byteString.substring(8,16));
byte[] array = new byte[] {a,b};
if(array[0] == nullCharBytes[0] && array[1] == nullCharBytes[1])return null;
var byteBuffer = ByteBuffer.wrap(array);
return byteBuffer.getChar(0);
}
public static String baum_to_byteString (Node baum)
{
if(baum == null)return "";
String byteString = character_to_byteString(baum.getBuchstabe());
byteString += baum_to_byteString(baum.getLeft());
byteString += baum_to_byteString(baum.getRight());
return byteString;
}
public static Node byteString_to_baum (String s)
{
Node root = null;
Stack<Node> äste = new Stack<Node>();
for(int i=0;i<s.length();i+=16)
{
String characterString = s.substring(i,i+16);
Character c = byteString_to_character(characterString);
Node node = new Node();
node.setBuchstabe(c);
if(i == 0)root = node;
if(äste.isEmpty() == false)
{
Node elternAst = äste.peek();
elternAst.add(node);
if(elternAst.hatPlatzKinder() == false)
{
äste.pop();
}
}
if(c == null)
{
äste.push(node);
}
}
return root;
}
public static Integer byteString_to_int(String byteString)
{
if(byteString.length() != 32)
{
System.out.println(">32");
return null;
}
int result = 0;
for(int i=0 ;i<32;i++)
{
if(byteString.charAt(31-i) == '1')result|=1<<i; //verschiebt die 1 um i binärpositionen nach links
else if(byteString.charAt(31-i) != '0')
{
System.out.println("was flasch");
return null;
}
}
return result;
}
public static String Int_to_ByteString (int a)
{
String result = "";
for(int i=0;i<32;i++)
{
boolean bit= ((a>>(31-i))&1)==1;
result+= bit?'1': '0'; //falls bit wert 1 hat addiert es 1 zu dem string, wenn nicht dann addiertes es 0
}
return result;
}
public static void compressFile (String source, String target )
{
Path sourcePath = Path.of(source);
Path targetPath = Path.of(target);
if(Files.exists(sourcePath) == false)
{
System.out.println("Datei nicht gefunden");
return;
}
String text;
try
{
text = Files.readString(sourcePath);
}
catch(Exception error)
{
System.out.println(error);
return;
}
String compressedText = codierungInklBaum(text);
try
{
Files.writeString(targetPath, compressedText);
}
catch(Exception error)
{
System.out.println(error);
return;
}
}
public static void readFile(String file)
{
Path path = Path.of(file);
if(Files.exists(path) == false)
{
System.out.println("Datei nicht gefunden");
return;
}
String compressedText;
try
{
compressedText = Files.readString(path);
}
catch(Exception error)
{
System.out.println(error);
return;
}
String text = decodierungInlkBaum(compressedText);
System.out.println(file+": " + text);
}
}