#include <iostream>
using namespace std;



class funcStr{
public:
    virtual char operator [] (unsigned int);
    virtual unsigned int size();
    virtual unsigned int find(char);
};

class fstr:public funcStr{
    unsigned int _size;
    char * _str;
public:
    fstr(char []);
    fstr(char [],int);
    char operator [] (unsigned int);
    unsigned int size();
    unsigned int find(char);
};

class fchg:public funcStr{
    funcStr * _from;
    char _c;
    unsigned int _i;
public:
    fchg(funcStr * from, char c, int i);
    char operator[](unsigned int);
    unsigned int size();
    unsigned int find(char);
};

class fsub:public funcStr{
    funcStr * _from;
    unsigned int _start,
                 _end;
public:
    fsub(funcStr * from, unsigned int start, unsigned int end);
    char operator[](unsigned int);
    unsigned int size();
    unsigned int find(char);
};

class fins:public funcStr{
    funcStr * _from,
            * _ins;
    unsigned int _i;
public:
    fins(funcStr * from, funcStr * ins, unsigned int i);
    char operator[](unsigned int);
    unsigned int size();
    unsigned int find(char);
};

class fstrip:public funcStr{
    funcStr * _from;
    unsigned int _start,
                 _end;
public:
    fstrip(funcStr * from, unsigned int start, unsigned int end);
    char operator[](unsigned int);
    unsigned int size();
    unsigned int find(char);
};

//base
char funcStr::operator[] (unsigned int)
{
    return 0;
}

unsigned int funcStr::size()
{
    return 0;
}

unsigned int funcStr::find(char c)
{
    return 0;
}
//string
fstr::fstr(char str[], int size)
{
    _str = str;
    _size = size;
}

fstr::fstr(char str[])
{
    _str = str;
    _size = 0;
    while(str[_size]!=0)
        _size++;
}

char fstr::operator[](unsigned int index)
{
    if (index < _size)
        return *(_str+index);
    return 0;
}

unsigned int fstr::size()
{
    return _size;
}

unsigned int fstr::find(char c)
{
    for (int i=0;i<_size;i++)
        if (*(_str+i)==c)
            return i;
    return _size;
}
    
    
//change

fchg::fchg(funcStr * from, char c, int i)
{
    _from = from;
    _i = i;
    _c = c;
}

char fchg::operator[](unsigned int index)
{
    if (index == _i)
        return _c;
    return (*_from)[index];
}

unsigned int fchg::size()
{
    return _from->size();
}

unsigned int fchg::find(char c)
{
    if (_c != c)
        return _from->find(c);
    return _i;
}

//substring

fsub::fsub(funcStr * from, unsigned int start, unsigned int end)
{
    _from = from;
    _start = start;
    _end = end;
}

char fsub::operator[](unsigned int index)
{
    if (index < _end-_start)
        return (*_from)[index+_start];
    return 0;
}

unsigned int fsub::size()
{
    return _end-_start;
}

unsigned int fsub::find(char c)
{
    //possible optimization
    for (int i=_start;i<_end;i++)
        if ((*_from)[i]==c)
            return i-_start;
    return _end-_start;
}

//insert
fins::fins(funcStr * from, funcStr * ins, unsigned int i)
{
    _from = from;
    _ins = ins;
    _i = i;
}

char fins::operator[](unsigned int i)
{
    if (i > _from->size() + _ins->size()-1)
        return 0;
    if (i < _i)
        return (*_from)[i];
    if (i < _i + _ins->size())
        return (*_ins)[i-_i];
    return (*_from)[i-_ins->size()];
}

unsigned int fins::size()
{
    return _from->size() + _ins->size();
}

unsigned int fins::find(char c)
{
    //possible optimization
    for (int i=0;i<size();i++)
        if (operator[](i)==c)
            return i;
    return size();
}

//fstrip
fstrip::fstrip(funcStr * from, unsigned int start, unsigned int end)
{
    _from = from;
    _start = start;
    _end = end;
}

char fstrip::operator[](unsigned int index)
{
    if (index > _from->size()-(_end-_start))
        return 0;
    if (index < _start)
        return (*_from)[index];
    return (*_from)[index-_start+_end];
}

unsigned int fstrip::size()
{
    return _from->size()-(_end-_start);
}

unsigned int fstrip::find(char c)
{
    //possible optimization
    for (int i=0;i<size();i++)
        if (operator[](i)==c)
            return i;
    return size();
}

