What is the MTF transform?
The MTF (Move to Front) is a data transformation algorithm that restructures data in such a way that the transformed message is more compressible and therefore used as an extra step in compression. Technically, it is an invertible transform of a sequence of input characters to an array of output numbers.
Why MTF?
- In many cases, the output array gives frequently repeated characters’ lower indexes which is useful in data compression algorithms.
- It is first of the three steps to be performed in succession while implementing Burrows – Wheeler Data Compression algorithm that forms the basis of the Unix compression utility bzip2.
The main idea behind MTF:
- The primary idea behind MTF is to maintain an ordered list of legal symbols (a to z, in our example).
- Read one character at a time from input string .
- Print out the position at which that character appears in the list.
- Move that character to front of the list and repeat the process until indexes for all input characters are obtained.
Illustration for "panama". List initially contains English alphabets in order. We one by one characters of input to front. input_str chars output_arr list p 15 abcdefghijklmnopqrstuvwxyz a 15 1 pabcdefghijklmnoqrstuvwxyz n 15 1 14 apbcdefghijklmnoqrstuvwxyz a 15 1 14 1 napbcdefghijklmoqrstuvwxyz m 15 1 14 1 14 anpbcdefghijklmoqrstuvwxyz a 15 1 14 1 14 manpbcdefghijkloqrstuvwxyz
Inference:
- If the letters occur many times in the input, then many of the output values will be small integers such as 0, 1, 2 etc.
- Thus, encoding extremely high frequency of these letters makes an ideal scenario for Huffman Coding.
Examples:
Input : panama Output : 15 1 14 1 14 1 Input : geeksforgeeks Output : 6 5 0 10 18 8 15 18 6 6 0 6 6
Following is the code for idea explained above:
// C++ program to find move to front transform of // a given string #include <iostream> #include <cstring> using namespace std;
// Returns index at which character of the input text // exists in the list int search( char input_char, char * list) {
for ( int i = 0; i < strlen (list); i++) {
if (list[i] == input_char) {
return i;
}
}
return -1;
} // Takes curr_index of input_char as argument // to bring that character to the front of the list void moveToFront( int curr_index, char * list) {
char record[26];
strncpy (record, list, 26);
// Characters pushed one position right
// in the list up until curr_index
for ( int i = curr_index; i > 0; i--) {
list[i] = record[i - 1];
}
// Character at curr_index stored at 0th position
list[0] = record[curr_index];
} // Move to Front Encoding void mtfEncode( char * input_text, int len_text, char * list) {
int output_arr[len_text];
for ( int i = 0; i < len_text; i++) {
// Linear Searches the characters of input_text
// in list
output_arr[i] = search(input_text[i], list);
// Printing the Move to Front Transform
cout << output_arr[i] << " " ;
// Moves the searched character to the front
// of the list
moveToFront(output_arr[i], list);
}
} // Driver program to test functions above int main() {
char * input_text = "panama" ;
int len_text = strlen (input_text);
// Maintains an ordered list of legal symbols
char list[26];
strcpy (list, "abcdefghijklmnopqrstuvwxyz" );
cout << "Input text: " << input_text << endl;
cout << "Move to Front Transform: " ;
// Computes Move to Front transform of given text
mtfEncode(input_text, len_text, list);
cout << endl;
return 0;
} // this code is contributed by bhardwajji |
// C program to find move to front transform of // a given string #include <stdio.h> #include <stdlib.h> #include <string.h> // Returns index at which character of the input text // exists in the list int search( char input_char, char * list)
{ int i;
for (i = 0; i < strlen (list); i++) {
if (list[i] == input_char) {
return i;
break ;
}
}
} // Takes curr_index of input_char as argument // to bring that character to the front of the list void moveToFront( int curr_index, char * list)
{ char * record = ( char *) malloc ( sizeof ( char ) * 26);
strcpy (record, list);
// Characters pushed one position right
// in the list up until curr_index
strncpy (list + 1, record, curr_index);
// Character at curr_index stored at 0th position
list[0] = record[curr_index];
} // Move to Front Encoding void mtfEncode( char * input_text, int len_text, char * list)
{ int i;
int * output_arr = ( int *) malloc (len_text * sizeof ( int ));
for (i = 0; i < len_text; i++) {
// Linear Searches the characters of input_text
// in list
output_arr[i] = search(input_text[i], list);
// Printing the Move to Front Transform
printf ( "%d " , output_arr[i]);
// Moves the searched character to the front
// of the list
moveToFront(output_arr[i], list);
}
} // Driver program to test functions above int main()
{ char * input_text = "panama" ;
int len_text = strlen (input_text);
// Maintains an ordered list of legal symbols
char * list = ( char *) malloc ( sizeof ( char ) * 26);
strcpy (list, "abcdefghijklmnopqrstuvwxyz" );
printf ( "Input text: %s" , input_text);
printf ( "\nMove to Front Transform: " );
// Computes Move to Front transform of given text
mtfEncode(input_text, len_text, list);
return 0;
} |
// Java program to find move to front transform of // a given string import java.util.Arrays;
public class Main {
// Returns index at which character of the input text
// exists in the list
static int search( char input_char, char [] list) {
for ( int i = 0 ; i < list.length; i++) {
if (list[i] == input_char) {
return i;
}
}
return - 1 ;
}
// Takes curr_index of input_char as argument
// to bring that character to the front of the list
static void moveToFront( int curr_index, char [] list) {
char record[] = Arrays.copyOf(list, list.length);
// Characters pushed one position right
// in the list up until curr_index
for ( int i = curr_index; i > 0 ; i--) {
list[i] = record[i - 1 ];
}
// Character at curr_index stored at 0th position
list[ 0 ] = record[curr_index];
}
// Move to Front Encoding
static void mtfEncode(String input_text, int len_text, char [] list) {
int [] output_arr = new int [len_text];
for ( int i = 0 ; i < len_text; i++) {
// Linear Searches the characters of input_text
// in list
output_arr[i] = search(input_text.charAt(i), list);
// Printing the Move to Front Transform
System.out.print(output_arr[i] + " " );
// Moves the searched character to the front
// of the list
moveToFront(output_arr[i], list);
}
}
// Driver program to test functions above
public static void main(String[] args) {
String input_text = "panama" ;
int len_text = input_text.length();
// Maintains an ordered list of legal symbols
char [] list = "abcdefghijklmnopqrstuvwxyz" .toCharArray();
System.out.println( "Input text: " + input_text);
System.out.print( "Move to Front Transform: " );
// Computes Move to Front transform of given text
mtfEncode(input_text, len_text, list);
System.out.println();
}
} // this code is contributed by bhardwajji |
# Python program for the above approach def search(input_char, lst):
"""
Returns index at which character of the input text
exists in the list.
"""
for i in range ( len (lst)):
if lst[i] = = input_char:
return i
def move_to_front(curr_index, lst):
"""
Takes curr_index of input_char as argument
to bring that character to the front of the list.
"""
record = lst[:]
lst[ 1 :curr_index + 1 ] = record[:curr_index]
lst[ 0 ] = record[curr_index]
def mtf_encode(input_text, lst):
"""
Move to Front Encoding.
"""
output_arr = []
for i in range ( len (input_text)):
# Linear Searches the characters of input_text in list
output_arr.append(search(input_text[i], lst))
# Printing the Move to Front Transform
print (output_arr[i], end = ' ' )
# Moves the searched character to the front of the list
move_to_front(output_arr[i], lst)
def main():
input_text = "panama"
len_text = len (input_text)
# Maintains an ordered list of legal symbols
lst = list ( "abcdefghijklmnopqrstuvwxyz" )
print (f "Input text: {input_text}" )
print ( "Move to Front Transform: " , end = '')
# Computes Move to Front transform of given text
mtf_encode(input_text, lst)
if __name__ = = "__main__" :
main()
# This code is contributed by Prince |
using System;
public class Program
{ // Returns index at which character of the input text
// exists in the list
static int Search( char inputChar, char [] list)
{
for ( int i = 0; i < list.Length; i++)
{
if (list[i] == inputChar)
{
return i;
}
}
return -1;
}
// Takes currIndex of inputChar as argument
// to bring that character to the front of the list
static void MoveToFront( int currIndex, char [] list)
{
// Create a copy of the current list for reference
var record = ( char [])list.Clone();
// Move characters to the right until currIndex is reached
for ( int i = currIndex; i > 0; i--)
{
list[i] = record[i - 1];
}
// Move the searched character to the front of the list
list[0] = record[currIndex];
}
// Move to Front Encoding
static void MtfEncode( string inputText, int lenText, char [] list)
{
// Create an array to store the output
var outputArr = new int [lenText];
for ( int i = 0; i < lenText; i++)
{
// Search for the current character in the list
outputArr[i] = Search(inputText[i], list);
// Print the index of the searched character in the list
Console.Write(outputArr[i] + " " );
// Move the searched character to the front of the list
MoveToFront(outputArr[i], list);
}
}
// Driver program to test functions above
public static void Main( string [] args)
{
// Set the input text and its length
var inputText = "panama" ;
var lenText = inputText.Length;
// Create a list of legal symbols in alphabetical order
var list = "abcdefghijklmnopqrstuvwxyz" .ToCharArray();
// Print the input text
Console.WriteLine( "Input text: " + inputText);
// Print the Move to Front Transform label
Console.Write( "Move to Front Transform: " );
// Computes Move to Front transform of given text
MtfEncode(inputText, lenText, list);
Console.WriteLine();
}
} |
// JavaScript program for the above approach function search(input_char, lst) {
/*
Returns index at which character of the input text
exists in the list.
*/
for (let i = 0; i < lst.length; i++) {
if (lst[i] === input_char) {
return i;
}
}
} function move_to_front(curr_index, lst) {
/*
Takes curr_index of input_char as argument
to bring that character to the front of the list.
*/
let record = lst.slice();
lst.splice(1, curr_index, ...record.slice(0, curr_index));
lst[0] = record[curr_index];
} function mtf_encode(input_text, lst) {
/*
Move to Front Encoding.
*/
let output_arr = [];
for (let i = 0; i < input_text.length; i++) {
// Linear Searches the characters of input_text in list
output_arr.push(search(input_text[i], lst));
// Printing the Move to Front Transform
process.stdout.write(output_arr[i] + " " );
// Moves the searched character to the front of the list
move_to_front(output_arr[i], lst);
}
} function main() {
let input_text = "panama" ;
let len_text = input_text.length;
// Maintains an ordered list of legal symbols
let lst = "abcdefghijklmnopqrstuvwxyz" .split( "" );
console.log(`Input text: ${input_text}`);
process.stdout.write( "Move to Front Transform: " );
// Computes Move to Front transform of given text
mtf_encode(input_text, lst);
} main(); // This code is contributed by adityashatmfh |
Input text: panama Move to Front Transform: 15 1 14 1 14 1
Time Complexity: O(n^2), where n is the length of given input_text
Auxiliary Space: O(n)
Exercise: Implement Inverse of Move to Front Transform.