//este recorrido lee el arbol armado con la frecuencia y devuelve cada caracter con su codigo huffman public static List <Arbol> recorridoArbol(Arbol A) { List <Arbol> pila = new List <Arbol>(); List <Arbol> codificacion = new List <Arbol>(); A.frec = ""; Arbol temp; while (A != null || pila.Count > 0) { while (A != null) { pila.Add(A); temp = A; A = A.hijoIzq; if (A != null) { A.frec = temp.frec + "0"; } } if (pila.Count > 0) { A = pila[pila.Count - 1]; pila.RemoveAt(pila.Count - 1); if (A != null && A.letra != null) { Arbol a = new Arbol(); a.letra = A.letra; a.frec = A.frec; codificacion.Add(a); } temp = A; A = A.hijoDer; if (A != null) { A.frec = temp.frec + "1"; } } } return(codificacion); }
//este es el metodo encargado de armar el arbol recibiendo las letras con su frecuencia y devolver el codigo huffman de cada letra public static List <Arbol> codificacionHuffman(List <Arbol> codigoFrec) { //primero invoca ordenar para oordenar la lista List <Arbol> codigo = ordenar(codigoFrec); //for(int i = 0; i < codigo.size(); i++)System.out.println(codigo.get(i).letra + " " + codigo.get(i).frec + " "); //aqui arma el arbol while (codigo.Count > 1) { Arbol a = new Arbol(); a.colocaIzq(codigo[0], a); a.colocaDer(codigo[1], a); codigo.RemoveAt(0); codigo.RemoveAt(0); a.frec = Convert.ToString(Convert.ToInt32(a.hijoDer.frec) + Convert.ToInt32(a.hijoIzq.frec)); codigo.Insert(buscarPosicion(codigo, a), a); } //finalmente invoca el metodo que recorre el arbol y arma el codigo huffman de cada caracter codigo = recorridoArbol(codigo[0]); return(codigo); }
public static int Main(string[] args) { if (args.Length < 3) { System.Console.WriteLine("Please enter one of the next posibilities of parameter"); System.Console.WriteLine("to compress: 0 <path to text file> <path to output>"); System.Console.WriteLine("to decompress: 1 <path to compressed file and keys file> <path to output>"); return(1); } int mode = Int32.Parse(args[0]); string inputPath = args[1]; string outputPath = args[2]; //Console.WriteLine(args[0] + " " + args[1] + " " + args[2]); //// test compress //int mode = 0; //string inputPath = "C:/Users/sebastian/Desktop/test.txt"; //string outputPath = "C:/Users/sebastian/Desktop/testOutput"; ////test decompress //int mode = 1; //string inputPath = "C:/Users/sebastian/Desktop/testOutput"; //string outputPath = "C:/Users/sebastian/Desktop/testOutput"; //Console.WriteLine(args.Length + " " + args[0] + " " + args[1]); List <Arbol> codific = new List <Arbol>(); if (mode == 0) { //Console.WriteLine("Ingrese el nombre del archivo"); //string nomTxt = Console.ReadLine(); //leer txt original string textOriginal = ""; try { string texto; StreamReader sr = new StreamReader(inputPath); texto = sr.ReadLine(); while (texto != null) { textOriginal += texto; texto = sr.ReadLine(); } sr.Close(); } catch (Exception ex) { Console.WriteLine("excepcion : " + ex.Message); } codific = contarFrec(textOriginal); List <Arbol> a = codificacionHuffman(codific); //crear txt con las claves try { File.Delete(outputPath + "/keysFile.txt"); string fileName = outputPath + "/keysFile.txt"; StreamWriter writer = File.AppendText(fileName); for (int i = 0; i < a.Count; i++) { writer.WriteLine(a[i].letra); writer.WriteLine(a[i].frec); } writer.Close(); } catch { Console.WriteLine("Decoding Error"); } //crear txt comprimido try { File.Delete(outputPath + "/compressedFile.txt"); string fileName = outputPath + "/compressedFile.txt"; StreamWriter writer = File.AppendText(fileName); string textoCom = comprimir(textOriginal, a); writer.WriteLine(textoCom); writer.Close(); byte[] arr = StringToBytesArray(textoCom); // as one just can write complete bytes, we need a way to know which // bits are just fillers and should be discarda when decode int correctionFactor = (arr.Length * 8) - textoCom.Length; //Insert correction factor at begining byte[] newValues = new byte[arr.Length + 1]; newValues[0] = Convert.ToByte(correctionFactor); Array.Copy(arr, 0, newValues, 1, arr.Length); Stream stream = new FileStream(outputPath + "/compressedFile.dat", FileMode.Create); BinaryWriter bw = new BinaryWriter(stream); foreach (var b in newValues) { bw.Write(b); } bw.Flush(); bw.Close(); } catch { Console.WriteLine("Decoding Error"); } Console.ReadKey(); } else { //decodificar archivo try { string texto; StreamReader sr = new StreamReader(inputPath + "/keysFile.txt"); texto = sr.ReadLine(); while (texto != null) { Arbol temp = new Arbol(); temp.letra = texto; texto = sr.ReadLine(); temp.frec = texto; codific.Add(temp); Console.WriteLine(temp.letra + " " + temp.frec); texto = sr.ReadLine(); } sr.Close(); } catch (Exception ex) { Console.WriteLine("excepcion : " + ex.Message); } string textoBin = ""; try { string texto; StreamReader sr = new StreamReader(inputPath + "/compressedFile.txt"); texto = sr.ReadLine(); while (texto != null) { //textoBin += texto; texto = sr.ReadLine(); } sr.Close(); string myString; using (FileStream fs = new FileStream(inputPath + "/compressedFile.dat", FileMode.Open)) using (BinaryReader br = new BinaryReader(fs)) { byte[] binaryArray = br.ReadBytes(Convert.ToInt32(fs.Length)); // Extract the correction factor and remove from array before continue decoding int correctionFactor = binaryArray[0]; byte[] newValues = new byte[binaryArray.Length - 1]; Array.Copy(binaryArray, 1, newValues, 0, newValues.Length); textoBin = bytesArrayToString(newValues); textoBin = textoBin.Substring(correctionFactor, textoBin.Length - correctionFactor); } } catch (Exception ex) { Console.WriteLine("excepcion : " + ex.Message); } try { File.Delete(outputPath + "/decompressedFile.txt"); string fileName = outputPath + "/decompressedFile.txt"; StreamWriter writer = File.AppendText(fileName); writer.WriteLine(decodificacionHuffman(codific, textoBin)); writer.WriteLine(""); writer.Close(); } catch { Console.WriteLine("Decoding Error"); } Console.ReadKey(); } return(0); }
public virtual void colocaDer(Arbol V, Arbol t) { t.hijoDer = V; }
public virtual void colocaIzq(Arbol V, Arbol t) { t.hijoIzq = V; }
//metodo encargado de reconstruir el arbol a partir del codigo de cada letra, con este arbol armado procede a coger el texto comprimido //y reemplazar el codigo con su letra, para finalmente devolver el texto descomprimido public static string decodificacionHuffman(List <Arbol> codificacion, string texto) { //aqui reconstruye el arbol Arbol decodif = new Arbol(); for (int i = 0; i < codificacion.Count; i++) { string letra = codificacion[i].letra; string codigoBin = codificacion[i].frec; Arbol temp = decodif; for (int j = 0; j < codigoBin.Length; j++) { if (codigoBin[j] == '0') { if (temp.hijoIzq == null) { temp.hijoIzq = new Arbol(); } temp = temp.hijoIzq; } else { if (temp.hijoDer == null) { temp.hijoDer = new Arbol(); } temp = temp.hijoDer; } if (j == codigoBin.Length - 1) { temp.letra = letra; } } temp = decodif; } //aqui decodifica el texto string textDec = ""; Arbol reco = decodif; int k = 0; while (k < texto.Length) { if (texto[k] == '0') { reco = reco.hijoIzq; } else { reco = reco.hijoDer; } if (reco.letra != null) { textDec += reco.letra; reco = decodif; } k++; } return(textDec); }
public Arbol() { hijoIzq = null; hijoDer = null; }