Task: LZW compression


C++: #include <string>
#include <map>




template <typename Iterator>
Iterator compress(const std::string &uncompressed, Iterator result) {
  
  int dictSize = 256;
  std::map<std::string,int> dictionary;
  for (int i = 0; i < 256; i++)
    dictionary[std::string(1, i)] = i;
  
  std::string w;
  for (std::string::const_iterator it = uncompressed.begin();
       it != uncompressed.end(); ++it) {
    char c = *it;
    std::string wc = w + c;
    if (dictionary.count(wc))
      w = wc;
    else {
      *result++ = dictionary[w];
      
      dictionary[wc] = dictSize++;
      w = std::string(1, c);
    }
  }
  
  
  if (!w.empty())
    *result++ = dictionary[w];
  return result;
}



template <typename Iterator>
std::string decompress(Iterator begin, Iterator end) {
  
  int dictSize = 256;
  std::map<int,std::string> dictionary;
  for (int i = 0; i < 256; i++)
    dictionary[i] = std::string(1, i);
  
  std::string w(1, *begin++);
  std::string result = w;
  std::string entry;
  for ( ; begin != end; begin++) {
    int k = *begin;
    if (dictionary.count(k))
      entry = dictionary[k];
    else if (k == dictSize)
      entry = w + w[0];
    else
      throw "Bad compressed k";
    
    result += entry;
    
    
    dictionary[dictSize++] = w + entry[0];
    
    w = entry;
  }
  return result;
}

#include <iostream>
#include <iterator>
#include <vector>

int main() {
  std::vector<int> compressed;
  compress("TOBEORNOTTOBEORTOBEORNOT", std::back_inserter(compressed));
  copy(compressed.begin(), compressed.end(), std::ostream_iterator<int>(std::cout, ", "));
  std::cout << std::endl;
  std::string decompressed = decompress(compressed.begin(), compressed.end());
  std::cout << decompressed << std::endl;
  
  return 0;
}







VB: Option Explicit
Const numchars=127  

Function LZWCompress(si)
  Dim oDict,  intMaxCode, i,z,ii,ss,strCurrent,strNext,j
  Set oDict = CreateObject("Scripting.Dictionary")
  ReDim a(Len(si))
  
  intMaxCode = numchars
  For i = 0 To numchars
    oDict.Add Chr(i), i
  Next
  
  strCurrent = Left(si,1)
  j=0
  For ii=2 To Len(si)
    strNext = Mid(si,ii,1)
    ss=strCurrent & strNext
    If oDict.Exists(ss) Then
      strCurrent = ss
    Else
      a(j)=oDict.Item(strCurrent) :j=j+1
      intMaxCode = intMaxCode + 1
      oDict.Add ss, intMaxCode
      strCurrent = strNext
    End If
  Next
  a(j)=oDict.Item(strCurrent) 
  ReDim preserve a(j)
  LZWCompress=a
  Set oDict = Nothing
End Function

Function lzwUncompress(sc)
  Dim intNext, intCurrent, intMaxCode, i,ss,istr,s,j
  s=""     
  reDim dict(1000)
  intMaxCode = numchars
  For i = 0 To numchars : dict(i)= Chr(i) :  Next
    intCurrent=sc(0)
    
    For j=1 To UBound(sc)
      ss=dict(intCurrent)
      s= s & ss
      intMaxCode = intMaxCode + 1
      intnext=sc(j)
      If intNext<intMaxCode Then
        dict(intMaxCode)=ss & Left(dict(intNext), 1)
      Else
        dict(intMaxCode)=ss & Left(ss, 1) 
      End If
      intCurrent = intNext
    Next
    s= s & dict(intCurrent)
    lzwUncompress=s
End function

Sub printvec(a)
  Dim s,i,x
  s="("
  For i=0 To UBound (a)
   s=s & x & a(i)
   x=", "
  Next 
  WScript.echo s &")"
End sub

Dim a,b
b="TOBEORNOTTOBEORTOBEORNOT"
WScript.Echo b
a=LZWCompress (b)
printvec(a)
WScript.echo lzwUncompress (a )
wscript.quit 1