Sunday, March 17, 2013

Decode a string

Q: We are given a char array like “a1b2c3″ we have to convert this array to array like this “abbccc” .This has to be done in place as we are given that array has just enough space to hold the expanded array. Here's an algorithm to solve this:

#include <iostream>

string decode(string estr){
    int patlen = estr.length();
    int reqdlen=0;
    for(int i=0;i<patlen;++i){
        if( isDigit(estr[i]) ){
            reqdlen+=estr[i]-'0';
        }
    }
 
    string ans;
    ans.resize(reqdlen);
    cout<<ans.length()<<endl;
    //case 1: if patlen >= reqdlen
    //e.g. a1 a1b2
    if( patlen  >= reqdlen ){
        int idx=0;
        char lastchar;
        for(int i=0;i<patlen;++i){
            if( isChar(estr[i]) ){
                lastchar = estr[i];
                ans[idx] = estr[i];
            }else if( estr[i] == '2' ){
              //a1b3 will never come
              //cout<    ans[idx] = lastchar;
              idx++;
            }
        }
    }else if( patlen < reqdlen ){
        //shrink the pattern by moving all chars with
        //count 1
        int idx =0;
        char lastchar;
        int newlen=0;
        for(int i=0;i<patlen;++i){
            if( isChar[estr[i]] ){
              ans[idx++] = estr[i];
            }else if( estr[i] != '1' ){
               idx++;
            }
        }

        newlen = idx;
        //now start filling from the back
        int lastdigit;
        idx=reqdlen-1;
        for(int i=newlen-1;i>=0;--i){
          if( isDigit(estr[i]))
            lastdigit=estr[i]-'0';
          else{
            for(int j=0;j<lastdigit;++j){
               ans[idx--]=estr[i];
            }
            lastdigit=1;
          }
        }
    }
 return ans;
}

int main() {
 cout<<decode("a1b1c1")<<endl;
 cout<<decode("a2b1c2")<<endl;
 cout<<decode("a2b2c2")<<endl;
 cout<<decode("a1b1c5")<<endl;
 cout<<decode("a9b1c5")<<endl;

 return 0;
}