#include<iostream>
#include<vector>
#include<sstream>
using namespace std;
struct Estado{
Estado(string s, string c):simbolo(s), cadena(c){}
string simbolo;
string cadena;
};
int buscarTerminal(string c, string S[], int n){
while( (--n) >= 0 ){
if( c == S[n] )
break;
}
return n;
}
int buscarNoTerminal(string c, string V[], int n){
while( (--n) >= 0 ){
if( c == V[n] )
break;
}
return n;
}
vector<string> getTokens(string cad, string V[], int v){
int i = 0, j , tam = cad.length();
vector<string> tokens ;
string actual;
bool encontrado;
actual = cad.substr(i,1);
while(i<tam){
encontrado = false;
j = 0;
while( j < v ){
if(actual == V[j]){
tokens.push_back(actual);
encontrado = true;
break;
}
++j;
}
if(!encontrado){
actual.append(cad.substr(++i,1));
continue;
}
++i;
actual = cad.substr(i,1);
}
return tokens;
}
vector<string> getNivel(string estado, Estado E[], int n){
vector<string> lineas ;
int i = 0;
bool encontrado = false;
while( (i < n ) & ~encontrado ){
if( estado == E[i].simbolo ){
lineas.push_back(E[i].cadena);
encontrado = true;
}
++i;
}
while( i < n ){
if( estado != E[i].simbolo ){
break;
}
lineas.push_back(E[i].cadena);
++i;
}
return lineas;
}
vector<string> mostrarNiveles(string nivel , int nivel_raiz , Estado E[], string S[] , string V[] ,
int e, int s, int v, ostringstream &os){
//cout << "MOSTRAR NIVELES 1.. " << nivel_raiz << " - NIVEL : "<< nivel << endl;
vector<string> tokens = getTokens(nivel,V,v);
vector<string> salida ;
string tmp ;
int i = 0, j, k;
int terminal;
//cout << "tokens : " ;
while( i < tokens.size() ){
//cout << tokens.at(i) << " - ";
terminal = buscarTerminal(tokens.at(i),S,s);
if( terminal != -1 ){
if( salida.size() == 0 )
tmp.append(tokens.at(i));
else{
k = 0;
while( k < salida.size() ){
salida.at(k).append(tokens.at(i));
++k;
}
}
}else{
vector<string> _tokens = getNivel(tokens.at(i),E,e);
j = 0;
if( salida.size() == 0 ){
while( j < _tokens.size() ){
salida.push_back( tmp + _tokens.at(j) );
++j;
}
tmp = "";
}else{
vector<string> _tmp ;
while( j < _tokens.size() ){
k = 0;
while( k < salida.size() ){
_tmp.push_back(salida.at(k) + _tokens.at(j) );
++k;
}
salida.insert(salida.begin(),_tmp.begin(),_tmp.end());
++j;
}
}
}
++i;
}
//cout << endl;
i = 0;
if(salida.size() == 0)
salida.push_back(tmp);
while ( i < salida.size() ){
os << ( nivel_raiz < 100 ? "0" : ( nivel_raiz < 10 ? "00" : "" ) ) << nivel_raiz << " " << salida.at(i) << endl;
++i;
}
return salida;
}
void mostrarNiveles(vector<string> nivel , int nivel_raiz , Estado E[], string S[] , string V[] ,
int e, int s, int v, ostringstream &os){
if(nivel_raiz==0)
return;
int i = 0;
vector< vector < string > > tmp;
while( i < nivel.size() ){
tmp.push_back( mostrarNiveles( nivel.at(i), nivel_raiz, E, S, V, e, s, v , os) );
++i;
}
i = 0;
while( i < tmp.size() ){
//cout << "Recursividad("<<nivel_raiz<<","<<i<<")." << endl;
mostrarNiveles( tmp.at(i), nivel_raiz-1, E, S, V, e, s, v, os );
++i;
}
}
int main(){
string V[] = {"v0","v1","v2","a","b","c"};
string S[] = {"a","b","c"};
Estado E[] = {
Estado("v0","aav0"),
Estado("v0","bv1"),
Estado("v1","cv2b"),
Estado("v1","cb"),
Estado("v2","bbv2"),
Estado("v2","bb")
};
vector<string> ini;
ini.push_back("v0");
ostringstream os;
os << "04 v0" << endl;
mostrarNiveles(ini,8,E,S,V,6,3,6,os);
cout << os.str();
return 0;
}