# Text verkleinern/komprimieren



## najjannaj (16. Jun 2005)

Hallo habe mir folgenden Code geschrieben:



```
public class textkomp2 {

	public static void main(String[] args) {
		String string = "TTTTEEEsst";
		String result = pack(string);
		System.out.println(result);
	}
	public static String pack(String string){ 
	      int index = 0; 
	      StringBuffer result = new StringBuffer(); 
	       
	      for(int i = 0, n = string.length(); i<n; i++){ 
	         if(string.charAt(index) != string.charAt(i)){
	        	if(i-index != 1){
	        		result.append(i-index); 
	        	}
	            result.append(string.charAt(index)); 
	            index = i; 
	         } 
	      } 
	      if(string.length()-index != 1){
	    	  result.append(string.length()-index);
	      }
	      result.append(string.charAt(index)); 
	       
	      return result.toString(); 
	   }
}
```


Das macht aus dem String  "TTTTEEEsst" -> "4T3E2st"! Nicht sehr effektiv reicht mir aber zum rumbasteln. Jetzt  muss ich das ganze nur noch wieder rückgänig bekommen und da happert es momentan an einer fernüntigen Idee und der Umsetzung. Könnte mir da jemand weiterhelfen bzw. hat da einer ne Idee?

Mit freundlichen Grüßen
najjannaj


----------



## KISS (16. Jun 2005)

deine strings lassen sich leider nicht deterministisch entpacken sobald zahlen in dem ursprungsstring verwendet werden


----------



## najjannaj (16. Jun 2005)

Genau das ist ja mein Problem! Hat sonst einer ne Idee wie ich denn Text komprimieren kann?


----------



## KISS (16. Jun 2005)

naja, nimm nen zipstream *g*
wenn du wirklich mit dem algo spielen willst, dann google mal nach lempel ziff welch oder markov

wenn du wirklich mit deinem beispiel weiter machen willst, musst du immer ein zahl setzen, also zb

f(TTTTEESST)=4T3E2S1T, ich rate dir aber es andersrum zu schreiben (T4E3S2T1) da sich das format leichter handlen laesst


----------



## najjannaj (17. Jun 2005)

Das mit denn Zahlen hab ich auch so gemacht! Aber bei dem Wort "Test" kommt nun "1T1e1s1t" raus das ist doppelt so lange wie vorher  Also vergrößerst sich das! Naja, egal! Dann lass ich es eben!


----------



## Sky (17. Jun 2005)

najjannaj hat gesagt.:
			
		

> Das mit denn Zahlen hab ich auch so gemacht! Aber bei dem Wort "Test" kommt nun "1T1e1s1t" raus das ist doppelt so lange wie vorher  Also vergrößerst sich das! Naja, egal! Dann lass ich es eben!


Nochmal der Hinweis: zipstream


----------



## KISS (17. Jun 2005)

tja, die komprimierung ist so eine geschichte. mit sehr kurzen daten hat man bei den meisten algorithmen das problem das sich die entrophi erhoeht.


----------



## Bleiglanz (17. Jun 2005)

vor allem dürfen keine zwei Codewörter den gleichen anfang haben

T44

kann ja aus

TTTT4

oder

TTTTTT...44mal..TTTT

entstanden sein 

so einfach geht das leider nicht


----------



## KISS (17. Jun 2005)

stimmt, eigentlich muesste man die tupel noch trennen, oder aber nur einstellige rle tags zulassen


----------



## Karl (17. Jun 2005)

Hallo,

wenn das Risiko groß ist, dass der String sich verlängert),
könnte es sinnvoll sein, grundsätzlich ein Zeichen als Flag zu "opfern".

Beispiel: 
komprimierter String ...
... beginnt mit 0 --> Rest ist unkomprimiert, 
... beginnt mit 1 --> Rest ist komprimiert
... beginnt mit was anderem --> StreamCorruptedException
... ist leer --> leer
... ist null --> null

Nach einer Kompression wird jeweils geprüft, ob das Ergebnis länger ist als der Eingangsstring und dann auf
'0' + str ausgewichen, sonst wird eine '1' für Kompression vor das Komprimat gesetzt.

Nochwas zur zip-Kompressionsidee: Prinzipiell kein Problem. Das Ergebnis ist aber ein Byte-Stream/ByteArray). Es ist in Java nicht ganz trivial, binäre Daten in einem String zu parken (klang so als wolltest Du als Ergebnis wieder einen String), der Header ist auch nicht gerade klein.

Gruß,
Karl


----------



## KISS (17. Jun 2005)

Also sooo unkomfortabbel ist das arbeiten mit byteAarrays nun auch nicht.
als kleines beispiel


```
public static void main(String[] args) throws IOException
    {
        test("Pack mich, ich mag das"); //$NON-NLS-1$
        System.out.println("------------------------"); //$NON-NLS-1$
        test("ein etwas laneger string, hoffentlich reicht es jetzt um mal wirklich zu komprimieren, lalalal daddel daddel asdpfomökydbnsdfghksdfngksdfnvkdfnvklsdfnvlksdfnvlksdfnvlkdsfnvlkjdsfnvlkjdsfvnlkjsdfnvfldksnvlksfdjnvsfdkljnvkjldfvn"); //$NON-NLS-1$
        
    }

    private static void test(final String input) throws IOException
    {
        System.out.println("orginal("+input.length()+"):\t"+input); //$NON-NLS-1$ //$NON-NLS-2$
        final ByteArrayOutputStream buffer=new ByteArrayOutputStream();
        final DeflaterOutputStream out=new GZIPOutputStream(buffer);
        out.write(input.getBytes());
        out.flush();
        out.close();
        final byte[] encoded = buffer.toByteArray();
        System.out.println("encoded("+encoded.length+"):\t"+Arrays.toString(encoded)); //$NON-NLS-1$ //$NON-NLS-2$
        final InflaterInputStream in=new GZIPInputStream(new ByteArrayInputStream(encoded));
        buffer.reset();
        while(in.available()>=1)
        {
            final int size=in.read(encoded,0,1); // geth nur bytewise, siehe doc zu available
            if(size>0)
            {
                buffer.write(encoded, 0, size);
            }
        }
        final String result = new String(buffer.toByteArray());
        System.out.println("result:\t"+result); //$NON-NLS-1$
    }
```


----------



## Icewind (17. Jun 2005)

bei text würd ich mal prinzipiell zu einer wörterbuchkompression raten... und da hast du auch noch einiges zu tun wenn du das selber schreiben willst


----------

