# Lauflängencodierung mit C++



## Gladiator6 (2. April 2008)

Hallo

Kennt jemand vielleicht ein fertiges Script um eine Lauflängencodierung so durchzuführen:

WWWBBBBBBBBWWW
WTTTTTTTWWWWWW

-->

14
3W 8B 4W 7T 6W

Ziel wäre es ein beliebiges Text File mit diesem Verfahren zu komprimieren!
Meine Kentnisse in C++ reichen jedoch im Moment nicht aus um das selber zu realisieren!


----------



## sheel (3. April 2008)

Hi,
für was ist denn der 14 ?
edit: ich könnts machen wenn ich das weis


----------



## Dario Linsky (3. April 2008)

Hi,



> für was ist denn der 14 ?


wenn ich raten müsste, würde ich sagen, dass das wohl die Anzahl der Zeichen pro Zeile ist.

Grüße, D.


----------



## Gladiator6 (3. April 2008)

Ja sorry, hätte ich wohl schreiben müssen!

Die erste Ziffer ist die Zeilenlänge!


----------



## devDevil (3. April 2008)

? Was ist, wenn keine einheitliche Zeilenlänge vorliegt?

-> Was du brauchst (<xyz> ist jeweils der Header):
(1) std::fstream <fstream>
(2) std::fstream::getline <fstream> (oder std::getline <string>)
(3) std::string <string>

-> Im Prinzip fängst du vorne an (in der Zeile), gehst solange weiter, bis du ein anderes Zeichen findest, die Distanz ist dann die Anzahl der Zeichen von einer Sorte, gehst dann hin und nimmst das neue Zeichen und gehst damit durch ...

```
const std::string source("WWWBBBBBBBBWWW");
std::stringstream ss_dest;

std::string::const_iterator it_last(source.begin());
for (std::string::const_iterator it(source.begin()); it != source.end(); ++it)
    if (*it_last != *it)
    {
        ss_dest << std::distance(it_last, it) << *it_last;
        it_last = it;
    }
```
so in etwa sollte das gehen. Nun wäre da aber noch ein Problem. So gehst du zeilenweise durch. Aber das lässt sich umgehen. Pack in "source" den kompletten Inhalt der Datei (vgl. std::istream::rdbuf() via std:stringstream)

```
std::ostringstream ss;
ss << my_file.rdbuf();
source = ss.str();
```


----------



## Gladiator6 (3. April 2008)

Danke für die Hilfe. Ich kenne mich ein wenig mit PHP aus und habe Grundkentnisse von C++. Aber meine Kentnisse reichen nicht aus um dein gepostetes Script zu verstehen, geschweige denn anzupassen!


----------



## devDevil (3. April 2008)

Hmm es geht auch einfacher ... ist dann aber nicht unbedingt besser und schneller 

```
const std::string source("WWWBBBBBBBBWWW"); // dein String ... ist egal was drin steht ;)
std::stringstream ss_dest; // da wird alles reingeschrieben ... streams sind einfacher zu nutzen und in dem nützlich

std::string::const_iterator it_last(source.begin()); // letztes zeichen ist am anfang das 1. zeichen
for (std::string::const_iterator it(source.begin()); it != source.end(); ++it) // jedes zeichen des string durchgehen
    if (*it_last != *it || (it + 1) == source.end()) // ist es ein anderes als die, auf die die beiden iterator(zeiger) verweisen?
    {   // ja, also müssen wir die alten daten auf jedenfall haben
        ss_dest << std::distance(it_last, it) << *it_last; // abstand der zeiger == anzahl der zeichen zwischen 1. zeichen von dieser sorte und letzem
        it_last = it; // das neue zeichen nehmen ...
    }
```
 vllt. ist es jetzt etwas leichter zu verstehen


----------

