Task: Move-to-front algorithm


C++: #include <iostream>
#include <iterator>
#include <sstream>
#include <vector>

using namespace std;

class MTF
{
public:
    string encode( string str )
    {
	fillSymbolTable();
	vector<int> output;
	for( string::iterator it = str.begin(); it != str.end(); it++ )
	{
	    for( int i = 0; i < 26; i++ )
	    {
		if( *it == symbolTable[i] )
		{
		    output.push_back( i );
		    moveToFront( i );
		    break;
		}
	    }
	}
	string r;
	for( vector<int>::iterator it = output.begin(); it != output.end(); it++ )
	{
	    ostringstream ss;
	    ss << *it;
	    r += ss.str() + " ";
	}
	return r;
    }

    string decode( string str )
    {
	fillSymbolTable();
	istringstream iss( str ); vector<int> output;
	copy( istream_iterator<int>( iss ), istream_iterator<int>(), back_inserter<vector<int> >( output ) );
	string r;
	for( vector<int>::iterator it = output.begin(); it != output.end(); it++ )
	{
	    r.append( 1, symbolTable[*it] );
	    moveToFront( *it );
	}
	return r;
    }

private:
    void moveToFront( int i )
    {
	char t = symbolTable[i];
	for( int z = i - 1; z >= 0; z-- )
	    symbolTable[z + 1] = symbolTable[z];

        symbolTable[0] = t;
    }

    void fillSymbolTable()
    {
        for( int x = 0; x < 26; x++ )
	    symbolTable[x] = x + 'a';
    }

    char symbolTable[26];
};

int main()
{
    MTF mtf;
    string a, str[] = { "broood", "bananaaa", "hiphophiphop" };
    for( int x = 0; x < 3; x++ )
    {
        a = str[x];
        cout << a << " -> encoded = ";
        a = mtf.encode( a );
        cout << a << "; decoded = " << mtf.decode( a ) << endl;
    }
    return 0;
}










Ada: with Ada.Text_IO;

procedure Move_To_Front is 
   
   subtype Lower_Case is Character range 'a' .. 'z';
   subtype Index is Integer range 0 .. 25;
   type Table is array (Index) of Lower_Case;
   Alphabet: constant Table := "abcdefghijklmnopqrstuvwxyz";
   type Number_String is array(Positive range <>) of Natural;
   
   function Encode(S: String) return Number_String is
      Key: Table := Alphabet;
   
      function Encode(S: String; Tab: in out Table) return Number_String is
	 
	 procedure Look_Up(A: in out Table; Ch: Lower_Case; Pos: out Index) is  
	 begin
	    for I in A'Range loop
	       if A(I) = Ch then 
		  Pos := I;
		  A := A(Pos) & A(A'First .. Pos-1) & A(Pos+1 .. A'Last);
		  return;
	       end if;
	    end loop;
	    raise Program_Error with "unknown character";
	 end Look_Up;
	 
	 Empty: Number_String(1 .. 0);
	 Result: Natural;   
      begin
	 if S'Length = 0 then 
	    return Empty;
	 else
	    Look_Up(Tab, S(S'First), Result);
	    return Result & Encode(S(S'First+1 .. S'Last), Tab);
	 end if;
      end Encode;
   
   begin
      return Encode(S, Key);
   end Encode;
      
   function Decode(N: Number_String) return String is
      Key: Table := Alphabet;
   
      function Decode(N: Number_String; Tab: in out Table) return String is
	 
	 procedure Look_Up(A: in out Table; Pos: Index; Ch: out Lower_Case) is  
	 begin
	    Ch := A(Pos);
	    A := A(Pos) & A(A'First .. Pos-1) & A(Pos+1 .. A'Last);
	 end Look_Up;
	 
	 Result: String(N'Range);
      begin
	 for I in N'Range loop
	    Look_Up(Tab, N(I), Result(I));
	 end loop;
	 return Result;
      end Decode;
      
   begin
      return Decode(N, Key);
   end Decode;
      
   procedure Encode_Write_Check(S: String) is
      N: Number_String := Encode(S);
      T: String := Decode(N);
      Check: String := (if S=T then "Correct!" else "*WRONG*!");
   begin
      Ada.Text_IO.Put("'" & S & "' encodes to");
      for Num of N loop
	 Ada.Text_IO.Put(Integer'Image(Num));
      end loop;
      Ada.Text_IO.Put_Line(". This decodes to '" & T & "'. " & Check);
   end Encode_Write_Check;
   
begin
   Encode_Write_Check("broood");
   Encode_Write_Check("bananaaa");
   Encode_Write_Check("hiphophiphop");
end Move_To_Front;