Kodierungsverfahren, um bestimmte Daten effektiver komprimieren zu können Aus Wikipedia, der freien Enzyklopädie
Move to front (englisch „Nach vorne verschieben“, auch: Rotierende Kodierung) ist ein Kodierungsverfahren, das sich gut eignet, um Daten, die aus der Burrows-Wheeler-Transformation stammen, weiterzuverarbeiten, um sie anschließend effektiver komprimieren zu können.
Die Eingabedaten für Move-to-Front sind ein endliches Alphabet und eine Zeichenkette aus diesem Alphabet. Bei dem Alphabet kann es sich zum Beispiel um ASCII oder Unicode handeln, aber auch um Bytes.
Die Ausgabe von Move-to-Front ist eine Folge natürlicher Zahlen, wobei jede der Zahlen kleiner als die Länge des Alphabets ist.
Move-to-Front-Kodierung:
Dieser Ablauf führt dazu, dass Zeichen, die häufig in der Eingabe vorkommen, während der Kodierung relativ weit vorne im Alphabet a stehen. Dadurch wiederum enthält die Ausgabe mehr kleine Zahlen als große, und das wiederum ist nützlich, um die Zahlenfolge anschließend zu komprimieren, etwa mit der Huffman-Kodierung.
Move-to-Front-Dekodierung:
Die Dekodierung funktioniert fast genauso wie die Kodierung, nur dass die Position, an der das Alphabet geändert wird, schon bekannt ist (die Zahl aus der Eingabe), während sie bei der Kodierung erst bestimmt werden muss.
Das folgende Beispiel in der Programmiersprache C# zeigt eine Implementierung der Move-to-Front-Kodierung und Dekodierung eines über die Konsole eingegebenen Texts.[1]
Code-Schnipsel |
using System.Text;
namespace MoveToFront
{
class Program
{
private static char[] symbolTable;
// Diese Methode entfernt das Zeichen mit dem Index charIndex aus dem Array symbolTable und fügt es vorn wieder an
private static void MoveToFront(int charIndex)
{
char toFront = symbolTable[charIndex];
for (int j = charIndex; j > 0; j--)
{
symbolTable[j] = symbolTable[j - 1];
}
symbolTable[0] = toFront;
}
// Diese Methode kodiert die Eingabedaten mit dem Move-to-Front-Algorithmus
public static int[] Encode(string input)
{
List<int> output = new List<int>();
foreach (char c in input)
{
for (int i = 0; i < 26; i++)
{
if (symbolTable[i] == c)
{
output.Add(i);
MoveToFront(i);
break;
}
}
}
return output.ToArray();
}
// Diese Methode dekodiert die Eingabedaten mit dem Move-to-Front-Algorithmus
public static string Decode(int[] input)
{
StringBuilder output = new StringBuilder(input.Length);
foreach (int n in input)
{
output.Append(symbolTable[n]);
MoveToFront(n);
}
return output.ToString();
}
// Hauptmethode, die das Programm ausführt
static void Main(string[] args)
{
// Schreibt das Alphabet in eine Array vom typ char
symbolTable = "abcdefghijklmnopqrstuvwxyz".ToCharArray();
// Initialisiert die Eingabedaten
string[] testInputs = new string[] { "broood", "bananaaa", "hiphophiphop" };
foreach (string s in testInputs)
{
Console.WriteLine($"Encoding for '{s}':");
// Array für die kodierten Daten
int[] encoding = Encode(s);
// Ausgabe der kodierten Daten auf der Konsole
foreach (int i in encoding)
{
Console.Write($"{i} ");
}
Console.WriteLine($"\nDecoding for '{s}':");
Console.WriteLine($"{Decode(encoding)}\n"); // Ausgabe der dekodierten Daten auf der Konsole
}
}
}
}
|
Die Zeichenkette „Mississippi“ soll mit dem MTF-Algorithmus kodiert werden. Das Alphabet, das dabei verwendet wird, sei (der Kürze wegen) „ABCIMPSabcimps“.
In der folgenden Tabelle ist Zeichen jeweils das Eingabezeichen, Alphabet das aktuelle Alphabet. Die Ausgabe ist die Position des Zeichens im aktuellen Alphabet (beginnend mit 0), und Alphabet' ist das neue Alphabet, das dadurch entsteht, dass das Eingabezeichen an den Anfang verschoben wird.
Zeichen | Alphabet | Ausgabe | Alphabet' |
---|---|---|---|
M | ABCIMPSabcimps | 4 | MABCIPSabcimps |
i | MABCIPSabcimps | 10 | iMABCIPSabcmps |
s | iMABCIPSabcmps | 13 | siMABCIPSabcmp |
s | siMABCIPSabcmp | 0 | siMABCIPSabcmp |
i | siMABCIPSabcmp | 1 | isMABCIPSabcmp |
s | isMABCIPSabcmp | 1 | siMABCIPSabcmp |
s | siMABCIPSabcmp | 0 | siMABCIPSabcmp |
i | siMABCIPSabcmp | 1 | isMABCIPSabcmp |
p | isMABCIPSabcmp | 13 | pisMABCIPSabcm |
p | pisMABCIPSabcm | 0 | pisMABCIPSabcm |
i | pisMABCIPSabcm | 1 | ipsMABCIPSabcm |
Das Ergebnis der Kodierung ist der Text (4,10,13,0,1,1,0,1,13,0,1). Wenn man die Umsortierung des Alphabets weglässt, erhält man zum Vergleich den Text (4,10,13,13,10,13,13,10,12,12,10). Man kann daran sehen, dass nach einer kurzen „Einarbeitungsphase“ (hier 3 Zeichen lang: 4,10,13) relativ häufig kleine Zahlen ausgegeben werden, was gut für eine anschließende Komprimierung ist.
Um MTF wieder zu dekodieren, geht man den umgekehrten Weg:
Die Zahlenfolge (4,10,13,0,1,1,0,1,13,0,1) soll unter Verwendung des Alphabets „ABCIMPSabcimps“ dekodiert werden. In der folgenden Tabelle ist Position die Zahl aus der zu dekodierenden Zahlenfolge und Zeichen das dekodierte Zeichen. Die Spalten Alphabet und Alphabet' sind genau die gleichen wie in der Kodiertabelle oben.
Position | Alphabet | Zeichen | Alphabet' |
---|---|---|---|
4 | ABCIMPSabcimps | M | MABCIPSabcimps |
10 | MABCIPSabcimps | i | iMABCIPSabcmps |
13 | iMABCIPSabcmps | s | siMABCIPSabcmp |
0 | siMABCIPSabcmp | s | siMABCIPSabcmp |
1 | siMABCIPSabcmp | i | isMABCIPSabcmp |
1 | isMABCIPSabcmp | s | siMABCIPSabcmp |
0 | siMABCIPSabcmp | s | siMABCIPSabcmp |
1 | siMABCIPSabcmp | i | isMABCIPSabcmp |
13 | isMABCIPSabcmp | p | pisMABCIPSabcm |
0 | pisMABCIPSabcm | p | pisMABCIPSabcm |
1 | pisMABCIPSabcm | i | ipsMABCIPSabcm |
Die Ausgabe der Dekodierung ist also wie erwartet „Mississippi“.
Seamless Wikipedia browsing. On steroids.