Attribute Parser

  • + 0 comments

    A lot of code but works. This will fail (Result "C") if use the next iput, but the tests of hackerrank do not have this kind of test, I do not know if it is because "valid nesting" condition.

    tag2.tag3~c

    #include <vector>
    #include <iostream>
    using namespace std;
    
    
    int main() {
        int n = 0;
        int q = 0;
        cin >> n;
        cin >> q;
        bool salto = false;
        string linea;
        string finalLinea = "*";
        string finalTags = "+";
        string lineaCompleta;
        vector<string> markup;
        vector<string> queries;
        vector<string> limpios;
    
        
        while (n)   //Guardar lineas que hay entre cada espacio.
        {
            cin >> linea;
            if(linea[0] == '<') //Remove "<" 
                linea = linea.substr(1, linea.length());
            //if(linea[0] == '/') //Remove "/" 
              //  linea = linea.substr(1, linea.length());
            if(linea[linea.length()-1] == '>') //Remove ">" at the end.
                linea = linea.substr(0, linea.length()-1);
            if(linea[0] == '"')
            {
                linea = linea.substr(1, linea.length());
                linea = linea.erase(linea.length()-1);
            }
            if(getchar() == '\n')
            {
               n--; 
               salto = true;
            }
                
            markup.push_back(linea);
            if(salto)   //Se termina la linea de lenguare hrml.
            {
               markup.push_back(finalLinea);
               salto = false;
            }   
            lineaCompleta += linea + ".";
        }
        
        //Terminamos con markup, que tiene todas las cadenas separadas y un * cuando termina una linea.
    
        for (int i = 0; i < q; i++) //Get each line for queries
        {
            getline(cin, linea);
            queries.push_back(linea);
        }
        
        int i = 0;
        int punto = 0;
        string tag;
        int uala = 0;
        string variable;
    
        int qq = q;
        int inicioPunto = 0;
        while(q--)
        {
            while(queries[i].find('.', punto) != queries[i].npos) //Mientras se sigan encontrando posiciones de punto
            {
                punto = queries[i].find('.', punto);
                tag = queries[i].substr(inicioPunto, punto-inicioPunto);
                limpios.push_back(tag);
                punto++;//pasando el . para buscar el siguiente punto
                inicioPunto = punto;
            }
            uala = queries[i].find('~');
            tag = queries[i].substr(punto, uala-punto);
            uala++; //Pasando el ~ inicia el nombre de variable
            variable = queries[i].substr(uala);
            limpios.push_back(tag);
            limpios.push_back(finalTags);
            limpios.push_back(variable);
            i++;
            inicioPunto = 0;
            punto = 0 ;
            uala = 0;
        }
        
        //Terminamos con limpios, que tiene todas las cadenas separadas y un + que le sigue el atributo.
    /*    cout << " Limpios" << endl;
        for (int i = 0; i<limpios.size() ;i++)
        {
            cout << limpios[i] << endl;
        }
    */
        bool sinoindex = false;
        i = 0;
        int j = 0;
        int contadorTag = 0;
        while(qq)
        {
            if (limpios[i] == markup[j] && i < limpios.size() && j < markup.size()) //Tag encontrado
            {
                for(int k = j; k < markup.size(); k++)
                {
                    if(limpios[i+1] == finalTags) //ya el siguiente es el valor ("+")
                    {
                        while(markup[j] != finalLinea) //("*")
                        {   
                            
                            if(markup[j] == limpios[i+2]) //Encontro el mismo atributo
                            {
                                if(contadorTag == 0)
                                    //cout << "Tag e index correcto: " << markup[j+2] << endl;
                                    cout << markup[j+2] << endl;
                                else //Se encontro atributo pero no esta correcto el indexado
                                    //cout << "Tag con atributo pero index incorrecto: " << contadorTag << endl;
                                    cout << "Not Found!" << endl;
                                
                                qq--;
                                contadorTag = 0;
                                i += 3;
                                j = 0; //Se termina busqueda y manda a inicio de markup
                                sinoindex = true;
                                break;
                            }
                            j++;
                        }
                        //Se encontro tag pero no atributo y se llego a final de linea
                        if(!sinoindex)
                        {
                            //cout << "Tag sin atributo" << endl;
                            cout << "Not Found!" << endl;
                            qq--;
                            contadorTag = 0;
                            i = i+3;
                            j = 0;
                        }
                        sinoindex= false;
                        break;
                    }
                    else 
                    {
                        while(markup[j] != finalLinea) // ("*")
                        {
                            j++;
                        }
                        j++;
                        i++;
                        break;
                    }
                }
            }
            //else if (markup[j][0] == '/')  //El tag no es el mismo, hay que ver si abre y cierra antes de encontrarlo
            else if (limpios[i] != markup[j] && i < limpios.size() && j < markup.size()) 
            {
                if (markup[j][0] == '/')
                {
                    contadorTag--;
                }
                
                else
                    contadorTag++;  //Tags encontrados que se deberian cerrar
                
                while(markup[j] != finalLinea && j < markup.size()) // ("*") Se mueve al siguiente tag
                {
                    j++;
                }
                j++;
            }
            else //se acabaron los tags
            {    
                cout << "Not Found!" << endl;
                //cout << "No hay tag" << endl;
                qq--;
                while(limpios[i] != finalTags && qq)
                {
                    i++;
                }
                i=i+2;
                j=0;
            }
        }
        
        return 0;
    }