Methoden String text komprimieren und dekomprimieren

Loddakwin

Aktives Mitglied
Hallo Leute,

ich weiss nicht ob das hier richtig ist aber ich frag hier einfach mal nach. Ich hab von der Uni folgende Aufgabe bekommen vielleicht wisst ihr ob es da irgendwo etwas zum nachlesen gibt. Ich erwarte keine fertiggestellte Aufgabe!

Erstellen Sie eine Methode

Java:
public static String compress(String text)

die den String text auf folgende Weise komprimiert. Es soll ein Teilstring gefunden werden, der text vorangestellt wird (mit Doppelpunkt als Trennzeichen) und in text überall durch einen Punkt ersetzt wird. Es soll jener Teilstring gewählt werden, der die größte Einsparung an gesamter String-Länge bringt (d.h. inklusive vorangestelltem Teilstring). Gibt es mehrere solche, soll der längste gewählt werden. Gibt es mehrere solche, soll jener gewählt werden, der am weitesten links steht. Falls es beim Ersetzen mehrere Möglichkeiten gibt, soll auch jene am weitesten links gewählt werden.

Erstellen Sie auch eine Methode

Java:
public static String decompress(String text)

die einen komprimierten String wieder in den ursprünglichen zurück verwandelt.

Danke im voraus!

lg lodi
 
Zuletzt bearbeitet:

rme

Top Contributor
Hm.. gibt es irgendeine Anforderung an die Laufzeit, zum Beispiel, dass es in O(n) laufen soll oder so?

Wenn nicht, könntest du (bildlich gedacht) eine Schablone über den Text schieben, die immer kleiner wird. Du fängst bei der Hälfte der Länge an, d.h. wenn der String die Länge 12 hat, prüfst du, ob die ersten 6 Zeichen identisch mit den letzten 6 sind.

Wenn nicht, machst du die Schablone kleiner (5 Zeichen im Beispiel) und schaust, ob der String in den entsprechenden Intervallen noch eine Übereinstimmung findet. Dabei musst du die Schablone aber schieben und nicht einfach dein Intervall unterteilen.

Das ist nur ein Denkanstoß, der noch weiter ausgebaut werden müsste ;)
 

Loddakwin

Aktives Mitglied
Sorry ich hab vergessen es wurde uns ein Beispiel mitgegeben sieht so aus:

Beispiele:

Ein Gedicht ist ein Gedicht ist ein Gedicht -> in Gedicht:E. ist e. ist e.

Trolo -> :Trolo

Trololo -> ol:Tr..o

Trolololo -> olo:Tr.l.

Trololololo -> olol:Tr..o

Danke für deinen Denkanstoß aber das lasst sich anhand dieses Beispiel wahrscheinlich so nicht lösen oder?
 
Zuletzt bearbeitet:

rme

Top Contributor
Hilft dir der Ansatz oben nicht dabei oder haben wir uns nur zeitlich überschnitten? Denn das Beispiel passt genau zu der Idee, die ich kurz angerissen habe.
 

Loddakwin

Aktives Mitglied
Ich muss zugeben ich bin ziemlich neu in der java Programmierung und erlich gesagt tu ich mir ziemlich schwer so algorithmisch zu denken um das in Programmcode niederzuschreiben :( aber ich versuchs jetzt mal mit deinem Lösungsansatz!

Runtime error meinst du ?
 
Zuletzt bearbeitet:

HarleyDavidson

Bekanntes Mitglied
Ich würde (nachdem du die Beispiele gepostet hast) genau andersherum vorgehen als rme vorgeschlagen hat.
Du fängst mit einer kleinen Schablone an (2 Zeichen) und schaust, wie oft dieser Teilstring im Komplettstring vorkommt. Diese Anzahl merkst du dir.

Dann erweiterst du die Schablone um ein Zeichen und schaust wieder. Und wieder speicherst du den Wert.

Die Werte vergleichst du nachher und derjenige Teilstring, der am meisten im Gesamtstring vorkommt, benutzt du zum komprimieren.
 

schleichdi

Neues Mitglied
Wie klein die Welt doch ist, das gleiche Problem hab ich auch :toll:

Bezüglich der schablone, soll ich mit dieser Methode:
static int occurrences(String text, String substring, int start)
arbeiten und die Erweiterung der Schablone mit einer Schleife machen.

Also 2 Zeichen prüfen, Schleifendurchlauf 3 Zeichen prüfen usw.
Das währ ein Denkanstoß aber wegen der Realisierung hab ich auch noch keine Lösung ;(
Bitte um einen Lösungsansatz :)

vielen dank
 

HarleyDavidson

Bekanntes Mitglied
Ich fand die Aufgabe so interessant, dass ich sie selbst mal implementiert habe.

Das ist der Ablauf fürs komprimieren:
  1. Lese einen String ein
  2. Übergebe ihn mit einem Zeichen an die Methode compress
  3. Beginne mit einem Suchpattern der Länge 2 und suche nach Substrings im Gesamtstring
  4. Die absolute Zeichenersparnis wird gespeichert und aktualisiert, wenn eine höhere gefunden wurde
  5. Die Größe der Suchpattern wird bis zur Hälfte der Gesamtlänge des Strings erhöht
  6. Das Pattern mit der größten Ersparnis wird ersetzt und als Ergebnis der Methode zurückgegeben.

Hier mal mein Code (Achtung Spoiler ;) )

Java:
public class CompressString
{

    public static void main( String[] args )
    {
        String text = "Das ist ein Gedicht ist ein Gedicht ist ein Gedicht.";
        //text = "Trolololo";

        String compressedText = compress( text, "#" );
        System.out.println( compressedText );
        System.out.println( decompress( compressedText, "#") );
    }

    /**
     * Komprimiert einen String auf Basis vom Ersetzen von Substrings durch 
     * ein einzelnes Zeichen
     * @param text Der zu komprimierende String
     * @param compressChar Das Zeichen, dass die Substrings ersetzen soll
     * @return Den komprimierten String
     */
    public static String compress( String text, String compressChar )
    {
        System.out.println( "Länge Originalstring: "+text.length() );
        //Maximale Ersparnis wird gesucht
        int maxSavings = 0;
        String bestPattern = "";
        //Patternsuche von 2 Zeichen bis text.length / 2
        for ( int pattersize = 2; pattersize <= text.length() / 2; pattersize++ )
        {
            //Kompletten String durchgehen
            for ( int j = 0; j < (text.length() + 1) - pattersize; j++ )
            {
                //Pattern bauen
                String pattern = text.substring( j, j + pattersize );
                //Vorkommen zählen
                int found = getOccurences( text, pattern );
                //Ersparnis: Anzahl Funde * Länge Pattern - Länge des Patterns (weil der ja am Anfang wieder hin kommt)+ 1 wegen dem Doppelpunkt + Anzahl Funde wegen dem Char
                int savings = (found * pattern.length()) - (pattern.length()+1+found);
                //System.out.println( "Pattern: '" + pattern + "', found: " + found + " , Ersparnis: " + savings + " Zeichen" );
                //Die Ersparnis ist größer / gleich gut als das bisher gefundene
                if ( savings > maxSavings )
                {
                    //Das Pattern wird gemerkt
                    bestPattern = pattern;
                    //Ersparnis wird gemerkt
                    maxSavings = savings;
                }
            }
        }
        //System.out.println( "BestPattern: "+bestPattern );
        String resultString = bestPattern+":"+text.replaceAll( bestPattern, compressChar);
        System.out.println( "Länge komprimierter String: "+resultString.length() );
        return resultString;
    }
    
    /**
     * Dekomprimiert einen komprimierten String
     * @param text Der komprimierte String
     * @param compressChar Das Kompressionszeichen
     * @return Den dekomrimierten String
     */
    public static String decompress(String text, String compressChar)
    {
        //Komprimierten String splitten
        String[] info = text.split(":");
        //Pattern extrahieren
        String pattern = info[0];
        //Eigentlichen String extrahieren
        String result = info[1];
        //Pattern einsetzen
        return result.replaceAll( compressChar, pattern);
    }

    /**
     * Liefert die Anzahl zurück, wie oft ein Teilstring in einem String
     * vorkommt
     *
     * @param text Der Gesamttext
     * @param pattern Der Teilstring
     * @return Die Anzahl, wie oft der Teilstring im String vorkommt.
     */
    public static int getOccurences( String text, String pattern )
    {
        int occurences = 0;
        boolean eagerMatching = false;
        if ( 0 != pattern.length() )
        {
            for ( int index = text.indexOf( pattern, 0 ); index != -1; index = text
                    .indexOf( pattern, eagerMatching ? index + 1 : index + pattern.length() ) )
            {
                occurences++;
            }
            return occurences;
        }
        return 0;
    }
}
 
Zuletzt bearbeitet:

Ikaron

Bekanntes Mitglied
Bei der Lösung über mir darf kein Doppelpunkt im Text enthalten sein, vielleicht solltest du das noch ausbessern, da es ja keine Bedingung ist.
 

Yanaya

Mitglied
Ich bin auch gerade mit dieser Aufgabe beschäftigt und habe bei der Überprüfung von HarleyDavidsons Code folgendes Problem:

Wenn ich es beim Abgabesystem prüfen lassen will, kommt bei mir diese Fehlermeldung:

Code:
Could not find method "public static String compress (String text)" in class Bsp06!
Exception in thread "test" java.lang.NoSuchMethodException: Bsp06.compress(java.lang.String)
at java.lang.Class.getMethod(Class.java:1655)
at test.run(Unknown Source)

weiß jemand was das bedeuten kann oder hat das selbe Problem?
Immerhin ist ja "public static String compress (String text)" im Code vorhanden.
Oder versteh ich da was falsch?
 

schleichdi

Neues Mitglied
@ HarleyDavidson
Vielen dank für deinen Lösungsvorschlag, musste ein paar Sachen anpassen bzw Reverse Engineeren ;).
Habe auch die "." & ":" Abfrage auch eingebaut

Hast alles super erklärt bis auf die getOcurrences Methode.
Die Methode an sich habe ich gut aber bei der for Schleife bin ich mir nicht so ganz sicher
Java:
 for ( int index = text.indexOf( pattern, 0 ); index != -1; index = text
                    .indexOf( pattern, eagerMatching ? index + 1 : index + pattern.length() ) )
wenns geht erklär mir das mit dem eagerMatching und dem "Doppelpunkt" index + pattern.length...

Sonst super Ansatz


@ Yanaya. Die Fehlermeldung kommt, weil du die compress und decompress methode nicht genau nach dem vorgegebenen Schema erstellt hast.

Gesucht war:
Java:
public static String compress(String text)

Die von HarleyDavidson ist:
Java:
public static String compress( String text, String compressChar )
Musst die Methode genau wie bei der Vorgabe anpassen sonst spackt das Abgabesystem.

Derzeit habe ich diese Fehlermeldung:
Java:
> java -classpath '/tmp/autoc-einfprog-0.5.4-8-g9133f88/check-30-7-1385450341' -Duser.language=EN -Duser.region=US -Xmx512M Tester

Error while testing String compress(String text).
Exception in thread "test" java.lang.Exception: wrong result!
at test.run(Unknown Source)

Hab die Methode aber so angepasst, dass der Methodenkopf den Vorgaben entspricht.
Sollte passen.

Aber enough Java 4 today sitze schon seit Mitternacht daran, (tja weil ich es immer schaffe erst am letzten Abend damit anzufangen) :bloed:
 

HarleyDavidson

Bekanntes Mitglied
Stimmt... Nach der for - Schleife war ich mental so durch :D weil ich echt am Grübeln war.
Hier die Erklärung:

Grundlegender Aufbau einer for-Schleife:

for (Teil 1; Teil 2; Teil 3)

Teil 1: "int index = text.indexOf( pattern, 0 )"
Hier wird die Zählvariable initialisiert.
"indexOf" gibt das erste Vorkommen des Patterns zurück.
Ab hier wird also das Vorkommen des Patterns gezählt

Teil 2: "index != -1"
Die Schleife wird so lange durchlaufen, solange index ungleich -1 ist.
Das kommt daher, da indexOf den Wert -1 zurück gibt, wenn das Pattern
nicht gefunden wurde

Teil 3: "index = text.indexOf( pattern, eagerMatching ? index + 1 : index + pattern.length()"
Hier wird es spannend. Die Zählvariable index wird nicht wie gewohnt hochgezählt sondern
nach jedem Durchlauf wird entweder:

- bei eagerMatching = true: Die Zählvariable um 1 erhöht
- bei eagerMatching = false: Die Zählvariable um die Länge des Patterns erhöht

Und ab dort wird wieder nach dem Pattern gesucht. Wird dieser nicht mehr gefunden, dann bricht
die Schleife ab, wie in Teil 2 definiert.
eagerMatching war dabei so ein kleiner Test ob es zu einer Performanzsteigerung / Ungenauigkeit
kommt. Ich konnte keine feststellen, aber vielleicht beobachtet ja noch mehr was.

Java:
    /**
     * Dekomprimiert einen komprimierten String
     *
     * @param text Der komprimierte String
     * @param compressChar Das Kompressionszeichen
     * @return Den dekomrimierten String
     */
    public static String decompress( String text, String compressChar )
    {
        //Komprimierten String splitten
        String[] info = text.split( ":" );
        //Pattern extrahieren
        String pattern = info[0];
        //Eigentlichen String extrahieren
        String result = info[1];
        //Pattern einsetzen
        return result.replaceAll( compressChar, pattern );
    }

    /**
     * Liefert die Anzahl zurück, wie oft ein Teilstring in einem String
     * vorkommt
     *
     * @param text Der Gesamttext
     * @param pattern Der Teilstring
     * @return Die Anzahl, wie oft der Teilstring im String vorkommt.
     */
    public static int getOccurences( String text, String pattern )
    {
        int occurences = 0;
        boolean eagerMatching = true;
        if ( 0 != pattern.length() )
        {
            for ( int index = text.indexOf( pattern, 0 ); index != -1; index = text.indexOf( pattern, eagerMatching ? index + 1 : index + pattern.length() ) )
            {
                occurences++;
            }
            return occurences;
        }
        return 0;
    }
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Klassen Fehler bei public void setLabelText(JLabel label, String text) Java Basics - Anfänger-Themen 11
J Erste Schritte Text Eingabe und Ausgabe mit String? Java Basics - Anfänger-Themen 26
I Nummern/Text aus String bekommen Java Basics - Anfänger-Themen 21
B Aus Text Zeile einen String herauslesen Java Basics - Anfänger-Themen 11
I String (Text) abschneiden Java Basics - Anfänger-Themen 2
H html-Text mit Formatierung in String speichern Java Basics - Anfänger-Themen 4
L Markierten text in string speichern Java Basics - Anfänger-Themen 8
C Text(String) als File handhaben Java Basics - Anfänger-Themen 13
H text string alle 100 zeichen in ein 1D array einlesen ? Java Basics - Anfänger-Themen 8
H String an Ende einer text File anhängen Java Basics - Anfänger-Themen 2
S private String text; -> "Illegal start of expression Java Basics - Anfänger-Themen 7
G Text String prüfen Java Basics - Anfänger-Themen 2
krgewb String mit Datumsangabe in Long umwandeln Java Basics - Anfänger-Themen 2
D String Groß/Kleinschreibung Ignorieren Java Basics - Anfänger-Themen 4
D Map<String, Integer> sortieren und der reinfolge nach die Glieder abfragen Java Basics - Anfänger-Themen 3
J Ähnlichen String in Liste finden Java Basics - Anfänger-Themen 6
Kartoffel_1 String transformation Java Basics - Anfänger-Themen 7
H String-Operation replace() - Zeichenkette verdoppeln Java Basics - Anfänger-Themen 2
K String analysieren Java Basics - Anfänger-Themen 27
Beowend String zu Date parsen Java Basics - Anfänger-Themen 1
Beowend String auf Satzzeichen überprüfen? Java Basics - Anfänger-Themen 6
H Liste nach String-Länge sortieren Java Basics - Anfänger-Themen 1
String in ArrayList umwandeln Java Basics - Anfänger-Themen 1
I Sass Compiler und String erhalten? Java Basics - Anfänger-Themen 7
Avalon String in Double bzw. Währung konvertieren Java Basics - Anfänger-Themen 6
T Methode akzeptiert String nicht Java Basics - Anfänger-Themen 18
F Arraylist<String>Ein Wort pro Zeile Java Basics - Anfänger-Themen 6
J Schlüsselworte Prüfen, ob ein bestimmtes, ganzes Wort in einem String enthalten ist. Java Basics - Anfänger-Themen 6
N String überprüfen Java Basics - Anfänger-Themen 3
E String zerlegen aus args Java Basics - Anfänger-Themen 1
M Long-Typ in String-Änderung führt zu keinem Ergebnis bei großer Zahl Java Basics - Anfänger-Themen 11
Ostkreuz String Exception Java Basics - Anfänger-Themen 8
W Items löschen aus String Array vom Custom Base Adapter Java Basics - Anfänger-Themen 2
MoxMorris Wie macht man String[] = String[] aus einer anderer Methode? Java Basics - Anfänger-Themen 18
J String Filter Java Basics - Anfänger-Themen 5
S String Array Buchstaben um einen gewissen Wert verschieben Java Basics - Anfänger-Themen 4
R Größter zusammenhängender Block gleicher Zeichen im String Java Basics - Anfänger-Themen 1
XWing Randomizer mit einem String Java Basics - Anfänger-Themen 2
D 2D Char Array into String Java Basics - Anfänger-Themen 2
H Cast von Float nach String klappt nicht Java Basics - Anfänger-Themen 12
I Zerlegen von String Java Basics - Anfänger-Themen 3
B Beliebiger String gegeben Suche Datum in String Java Basics - Anfänger-Themen 6
I String Java Basics - Anfänger-Themen 4
I API - zurückgegebener JSON String lesen und in Entity konvertieren Java Basics - Anfänger-Themen 2
H Zu langen String aufteilen - bequeme Methode? Java Basics - Anfänger-Themen 14
W String einer Textdatei in einzelne Stringobjekte pro Zeile aufteilen Java Basics - Anfänger-Themen 14
belana wie am besten 2D Array von String to Integer Java Basics - Anfänger-Themen 18
J Java To String Methode, Array mit For-Schleife Java Basics - Anfänger-Themen 2
M Kommandozeilenparamter als EINEN String werten Java Basics - Anfänger-Themen 5
M RandomAccessFile int und String gleichzeitig in einer Datei Java Basics - Anfänger-Themen 49
M Prüfen on eine Zahl im String enthalten ist Java Basics - Anfänger-Themen 3
Distanz zwischen zwei Zeichenfolgen in einem String bestimmen Java Basics - Anfänger-Themen 5
Substring in einem String finden Java Basics - Anfänger-Themen 13
BeginnerJava String mit vorgegebener Länge und Buchstaben erzeugen/ mit Leerstellen Java Basics - Anfänger-Themen 8
I Eindeutiger String mit maximaler Anzahl an Zeichen Java Basics - Anfänger-Themen 11
H Interface Wieso "List<String> list = new ArrayList<>[…]" Java Basics - Anfänger-Themen 4
JavaBeginner22 Integer in String umwandeln Java Basics - Anfänger-Themen 7
HolyFUT JSON String in Java Object schreiben - Anführungszeichen rauskriegen? Java Basics - Anfänger-Themen 17
Fodoboo131 RegEx- Umwandlung von String in ausführbares Objekt/ Befehl Java Basics - Anfänger-Themen 9
HolyFUT Input/Output Leerzeichen aus String entfernen - klappt nicht! Java Basics - Anfänger-Themen 13
viktor1 Methoden Methode schreiben static void readText (String filename) {...} zu WordHistogramSample.java Java Basics - Anfänger-Themen 13
ravenz Schleife mit for über String Array „zahlen“und prüfen ob Wert „a“ oder „b“ oder „c“ entspricht (mittels || ) Java Basics - Anfänger-Themen 4
G Position einer unbekannten 3-stelligen-Zahl in einem String finden Java Basics - Anfänger-Themen 15
T String Array Fehler beim Index Java Basics - Anfänger-Themen 3
H Erste Schritte Nach einer Zahl n soll n Mal der String untereinander ausgegeben werden Java Basics - Anfänger-Themen 3
X Datentypen String.equals funktioniert nicht Java Basics - Anfänger-Themen 5
Alen123 String wiederholen mit Schleifen Java Basics - Anfänger-Themen 1
A String split funktioniert nicht, wenn mehr als 1 Ziffer vor dem Zeichen steht nach dem er trennen soll? Java Basics - Anfänger-Themen 4
T String splitten Java Basics - Anfänger-Themen 3
sserio Schwimmen als Spiel. Problem mit to String/ generate a card Java Basics - Anfänger-Themen 4
J Datentypen String in File konvertieren funktioniert nicht Java Basics - Anfänger-Themen 4
T Platzhalter in String? Java Basics - Anfänger-Themen 14
M String mit Variable vergleichen Java Basics - Anfänger-Themen 9
I String Kombination erstellen anhand fortlaufender Zahl (Vertragsnummer) Java Basics - Anfänger-Themen 13
Fats Waller Compiler-Fehler Kann ich einen String und die Summe zweier Char Werte mittels der println Anweisung ausgeben Java Basics - Anfänger-Themen 4
M Wie kann eine Methode (string) eine andere Methode (void) mit zufälligen int-Werten aufrufen? Java Basics - Anfänger-Themen 4
P9cman Vokale in einem String überprüfen mittels Rekursion Java Basics - Anfänger-Themen 8
schredder Strings und reguläre Ausdrücke - Methode mit return string.matches Java Basics - Anfänger-Themen 5
R Ein Multidimensionales String Array initialisieren und Deklarieren Java Basics - Anfänger-Themen 2
H String Repräsentation eines Rechtecks mit Instanz-Methode Java Basics - Anfänger-Themen 8
Dorfschmied Kartesisches Produkt von zwei Liste mit Hashmaps<String,String> erstellen Java Basics - Anfänger-Themen 4
S String mit Int input vergleichen Java Basics - Anfänger-Themen 5
C String/Char-API Java Basics - Anfänger-Themen 13
U Char zu einem String machen Java Basics - Anfänger-Themen 1
B Anzahl Nullen uns Einsen in String ermitteln Java Basics - Anfänger-Themen 3
T Leerzeichen im String entfernen Java Basics - Anfänger-Themen 6
Jose05 Nullpointerexception bei Umwandlung von String zu int Java Basics - Anfänger-Themen 2
O Ich habe einen String und soll mit matches schauen, ob ein Buchstabe zu einer geraden ANzahl im String vorkommt, wie soll das gehen? Java Basics - Anfänger-Themen 7
M String beim einlesen formatieren Java Basics - Anfänger-Themen 12
N null in String replacen Java Basics - Anfänger-Themen 16
R Compiler-Fehler JTable mit XML befüllen | The constructor JTable(Object[], String[]) is undefined Java Basics - Anfänger-Themen 10
M Eclipse kennt keine String Klasse mehr Java Basics - Anfänger-Themen 1
M Frage zur Methode split der Klasse String Java Basics - Anfänger-Themen 32
D String mit int multiplizieren? Java Basics - Anfänger-Themen 16
H Überprüfen ob String Array leer ist Java Basics - Anfänger-Themen 4
A Korrigierte <String> Liste zurückgeben Java Basics - Anfänger-Themen 22
C In String, Buchstaben ersetzen durch andere Buchstaben Java Basics - Anfänger-Themen 26
Poppigescorn String mit mehreren Wörtern füllen? Java Basics - Anfänger-Themen 4
I String Expression mit Java validieren (true / false) Java Basics - Anfänger-Themen 34
B String - Wörter finden, welches Punkt und entsprechender Pre / Suffix hat? Java Basics - Anfänger-Themen 30

Ähnliche Java Themen

Neue Themen


Oben