Nadesłany przez Tomasz Lubiński, 16 czerwca 2007 01:00
Kod przedstawiony poniżej przedstawia główną część rozwiązania problemu.Pobierz pełne rozwiązanie.
Jeżeli nie odpowiada Ci sposób formatowania kodu przez autora skorzystaj z pretty printer'a i dostosuj go automatycznie do siebie.
RLE.java:
// Kompresja RLE (Run Length Encoding) // www.algorytm.org // (c) 2007 by Tomasz Lubinski import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class RLE { /* kompresja RLE */ static void compress(FileInputStream in, FileOutputStream out) throws IOException { byte cur[] = new byte[1]; byte prev[] = new byte[1]; byte tmp[] = new byte[1]; char cnt = 0; int cont; cont = in.read(cur, 0, 1); prev[0] = (byte) ~cur[0]; while (cont == 1) { if (prev[0] != cur[0]) { if (cnt == 0) { /* znaki obok siebie rozne wrzuc do pliku wyjsciowego */ out.write(cur, 0, 1); } else { /* skonczyla sie sekwencja powtarzajcych sie znakow */ cnt--; out.write(prev, 0, 1); tmp[0] = (byte) cnt; out.write(tmp, 0, 1); out.write(cur, 0, 1); cnt = 0; } } else { /* liczbe powtarzajacych sie znakow zapisujemy na jednym bajcie wypisz sekwencje jezeli ma ona maksymalna dlugosc */ if (cnt == 255) { out.write(prev, 0, 1); tmp[0] = (byte) cnt; out.write(tmp, 0, 1); cnt = 0; cont = in.read(cur, 0, 1); prev[0] = (byte) ~cur[0]; continue; } else { /* licz powtarzajace sie znaki */ cnt++; } } /* odczytaj kolejny znak z pliku wejsciowego */ cont = in.read(tmp, 0, 1); if (cont == 1) { prev[0] = cur[0]; cur[0] = tmp[0]; } } /* jezeli plik konczy sie sekwencja wypisz ja */ if (prev[0] == cur[0]) { cnt--; out.write(prev, 0, 1); tmp[0] = (byte) cnt; out.write(tmp, 0, 1); } } /* dekompresja RLE */ static void decompress(FileInputStream in, FileOutputStream out) throws IOException { byte cur[] = new byte[1]; byte prev[] = new byte[1]; byte cnt[] = new byte[1]; int cont, i; cont = in.read(cur, 0, 1); prev[0] = (byte) ~cur[0]; while (cont == 1) { if (prev[0] != cur[0]) { /* znaki obok siebie rozne wrzuc do pliku wyjsciowego */ out.write(cur, 0, 1); prev[0] = cur[0]; /* odczytaj kolejny znak */ cont = in.read(cur, 0, 1); } else { /* znaki obok siebie sa rowne - mamy sekwencje */ /* odczytaj dlugosc sekwencji i wrzuc ja do pliku wyjsciowego */ cont = in.read(cnt, 0, 1); for (i=0; i<=(char)(cnt[0]&0xFF); i++) { out.write(cur, 0, 1); } /* odczytaj kolejny znak */ cont = in.read(cur, 0, 1); prev[0] = (byte) ~cur[0]; } } } /** * @param args * @throws IOException * @throws */ public static void main(String[] args) throws IOException { int x; String inPath; String outPath; File in, out; System.out.println("1 - kompresja"); System.out.println("2 - dekompresja"); x = Console.readInt(""); System.out.println("Plik wejsciowy:"); inPath = Console.readString(); System.out.println("Plik wyjsciowy:"); outPath = Console.readString(); in = new File(inPath); out = new File(outPath); if (x == 1) compress(new FileInputStream(in), new FileOutputStream(out)); else decompress(new FileInputStream(in), new FileOutputStream(out)); } }