# include <iostream>
# include <fstream>
# include <string>
# include <vector>
# include <sstream>
# include <algorithm>
# include <iterator>
# include <sstream>
std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
return elems;
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, elems);
return elems;
}
bool BothAreSpaces(char lhs, char rhs) {
return (lhs == rhs) && (lhs == ' ');
}
int what ( std :: string sir ) {
std :: string const paranteza_deschisa ("[");
std :: string const paranteza_inchisa ("]");
std :: string const acolada_deschisa ("{");
std :: string const acolada_inchisa ("}");
if ( sir.find(paranteza_deschisa) != std :: string :: npos) {
if ( sir.find(acolada_deschisa) != std :: string :: npos) {
// am acolada si paranteza deschisa
return 1;
}
return 0;
// am doar paranteza deschisa
} else if ( sir.find(acolada_deschisa) != std :: string :: npos ) {
if ( sir.find(acolada_inchisa) != std :: string :: npos ) {
// am acolada inchisa si deschisa
return 3;
}
// am doar acolada deschisa
return 2;
} else if ( sir.find(acolada_inchisa) != std :: string :: npos ) {
if ( sir.find(paranteza_inchisa) != std :: string :: npos ) {
// am acolada inchisa si paranteza inchisa
return 5;
}
// am doar acolada inchisa
return 4;
} else if ( sir.find(paranteza_inchisa) != std :: string :: npos ) {
// am doar paranteza inchisa
return 6;
}
return -1;
}
int second_what( std :: string cuvant ) {
std :: string const paranteza_deschisa ("[");
std :: string const paranteza_inchisa ("]");
std :: string const acolada_deschisa ("{");
std :: string const acolada_inchisa ("}");
std :: string const virgula (",");
std :: string const puncte(":");
if ( cuvant.find(paranteza_deschisa) != std :: string :: npos ) {
return 0; // am gasit o paranteza deschisa
} else if ( cuvant.find(acolada_deschisa) != std :: string :: npos ) {
return 1 ; // am gasit o acolada deschisa
} else if ( cuvant.find(puncte) != std :: string :: npos ) {
return 2; // am gasit 2 puncte
} else if ( cuvant.find(virgula) != std :: string :: npos ) {
return 3;// am gasit virgula
} else if ( cuvant.find(acolada_inchisa) != std :: string :: npos ) {
return 4;// am gasit acolada inchisa
} else if ( cuvant.find(paranteza_inchisa) != std :: string :: npos ) {
return 5;
}
return -1;
}
int virgula ( std :: string cuvant ) {
std :: string virgula (",");
if ( cuvant.find(virgula) != std :: string :: npos ) {
// am virgula
if ( cuvant.size() > 3 ) {
// atunci am virgula si valoare
return 0;
} else {
// am doar virgula si poate o cifra si virgula
return 1;
}
} else {
// valoarea nu are virgula
return 2;
}
}
int doua_puncte ( std :: string cuvant ) {
std :: string puncte (":");
if ( cuvant.find(puncte) != std :: string :: npos ) {
// valoarea are doua puncte => valoarea este int
return 0;
} else {
// valoarea nu are doua puncte
return 1;
}
}
int main () {
std :: ifstream f ("convertor.in");
std :: ofstream g ("convertor.out");
// constante :
std :: string const paranteza_deschisa ("[");
std :: string const paranteza_inchisa ("]");
std :: string const acolada_deschisa ("{");
std :: string const acolada_inchisa ("}");
std :: string const virgula (",");
std :: string const space (" ");
std :: string const puncte (":");
// variabile
std :: vector < std :: pair <std :: string,std :: vector <std :: string> > > hashTable;
std :: vector <std :: string > spart;
std :: string myWord;
std :: vector < std :: string > cuvinte ;
bool for_ever = true;
while ( for_ever == true ) {
std :: getline ( f, myWord );
std :: size_t pos = myWord.find(paranteza_inchisa);
if ( pos != std :: string :: npos ) {
for_ever = false;
}
// _start_prelucrare_linie
// trebuie sa inserez spatiu inainte de virgula
std :: size_t found = myWord.find(acolada_deschisa);
if ( found != std :: string :: npos ) {
myWord = myWord.insert (found,1,' ');
}
found = myWord.find(acolada_deschisa);
if ( found != std :: string :: npos ) {
myWord = myWord.insert (found+1,1,' ');
}
found = myWord.find(acolada_inchisa);
if ( found != std :: string :: npos ) {
myWord = myWord.insert (found,1,' ');
}
found = myWord.find(acolada_inchisa);
if ( found != std :: string :: npos ) {
myWord = myWord.insert (found+1,1,' ');
}
std::string::iterator new_end = std::unique(myWord.begin(), myWord.end(), BothAreSpaces);
myWord.erase(new_end, myWord.end());
spart = split ( myWord, '"' );
for (unsigned int j = 0; j < spart.size(); j ++ ) {
if ( spart[j].size() == 0 ) {
;
}else if ( what(spart[j]) == 0 || what(spart[j]) == 2 ||
what ( spart[j] ) == 6 ) {
std::string::iterator end_pos = std::remove(spart[j].begin(), spart[j].end(), ' ');
spart[j].erase(end_pos, spart[j].end());
cuvinte.push_back( spart[j] );
} else if ( what(spart[j]) == 1 ) {
// am acolada si paranteza, ambele deschise
std :: vector < std :: string > s = split ( spart[j], ' ' );
unsigned int p = 0 ;
while ( p < s.size () ) {
if ( s[p].size() == 0 ) ;
else
if ( s[p].find(paranteza_deschisa) != std :: string :: npos ||
s[p].find(acolada_deschisa) != std :: string :: npos ||
s[p].find(virgula) != std :: string :: npos ) {
cuvinte.push_back(s[p]);
}
p ++;
}
} else if ( what(spart[j]) == 3 ) {
// am acolada inchisa si deschisa
std :: size_t found = spart[j].find(virgula);
if ( found != std :: string :: npos ) {
spart[j] = spart[j].insert (found,1,' ');
}
found = spart[j].find(virgula);
if ( found != std :: string :: npos ) {
spart[j] = spart[j].insert (found+1,1,' ');
}
std :: vector < std :: string > s = split ( spart[j], ' ' );
unsigned int p = 0 ;
while ( p < s.size () ) {
if ( s[p].size() == 0 ) ;
else
if ( s[p].find(acolada_inchisa) != std :: string :: npos ||
s[p].find(acolada_deschisa) != std :: string :: npos||
s[p].find(virgula) != std :: string :: npos ) {
cuvinte.push_back(s[p]);
}
p ++;
}
} else if ( what(spart[j]) == 5 ) {
// am acolada si paranteza, ambele inchise
std :: vector < std :: string > s = split ( spart[j], ' ' );
unsigned int p = 0 ;
while ( p < s.size () ) {
if ( s[p].size() == 0 ) ;
else
if ( s[p].find(paranteza_inchisa) != std :: string :: npos ||
s[p].find(acolada_inchisa) != std :: string :: npos ||
s[p].find(virgula) != std :: string :: npos) {
cuvinte.push_back(s[p]);
}
p ++;
}
} else if ( what(spart[j]) == 4 ) {
std :: size_t found = spart[j].find(virgula);
if ( found != std :: string :: npos ) {
spart[j] = spart[j].insert (found,1,' ');
}
found = spart[j].find(virgula);
if ( found != std :: string :: npos ) {
spart[j] = spart[j].insert (found+1,1,' ');
}
std :: vector < std :: string > s = split ( spart[j], ' ' );
unsigned int p = 0 ;
while ( p < s.size () ) {
if ( s[p].size() == 0 ) ;
else
if ( s[p].find(acolada_inchisa) != std :: string :: npos ||
s[p].find(virgula) != std :: string :: npos ) {
cuvinte.push_back(s[p]);
}
p ++;
}
} else if ( spart[j].find( puncte ) != std :: string :: npos ||
spart[j].find(virgula) != std :: string :: npos ) {
std :: size_t found = spart[j].find(virgula);
if ( found != std :: string :: npos ) {
spart[j] = spart[j].insert (found,1,' ');
}
found = spart[j].find(virgula);
if ( found != std :: string :: npos ) {
spart[j] = spart[j].insert (found+1,1,' ');
}
found = spart[j].find(puncte);
if ( found != std :: string :: npos ) {
spart[j] = spart[j].insert (found,1,' ');
}
found = spart[j].find(puncte);
if ( found != std :: string :: npos ) {
spart[j] = spart[j].insert (found+1,1,' ');
}
std :: vector < std :: string > s = split ( spart[j], ' ' );
unsigned int p = 0 ;
while ( p < s.size () ) {
if ( s[p].size() == 0 ) ;
else
if ( s[p].find(virgula) != std :: string :: npos ||
s[p].find(puncte) != std :: string :: npos ||
s[p].find(space) == std :: string :: npos ) {
cuvinte.push_back(s[p]);
}
p ++;
}
} else if ( !( spart[j].size() == 1 && spart[j].find(space)
!= std :: string :: npos ) ) {
cuvinte.push_back(spart[j]);
}
}
// _end_prelucrare_linie
}
// eu am toate cuvintele intr-un vector
unsigned int i = 0 ;
while ( i < cuvinte.size() - 1) {
if ( second_what(cuvinte[i]) == 0 ) ;
else if ( second_what(cuvinte[i]) == 1 ) {
// am acolada deschisa => am doua cazuri : ori e prima, ori e a doua
if ( second_what(cuvinte[i-1]) == 0 ) {
// este prima acolada din json
std :: vector <std :: string> array;
std :: pair < std :: string, std :: vector < std :: string > > prima_pereche;
prima_pereche.first = cuvinte[i+1];
// i+3 este valoarea
array.push_back(cuvinte[i+3]);
prima_pereche.second = array;
hashTable.push_back(prima_pereche);
i = i + 3;
} else {
// nu este prima acolada
hashTable[0].second.push_back(cuvinte[i+3]);
i = i + 3;
}
} else if ( second_what(cuvinte[i]) == 3 ) {
// am virgula => am doua cazuri : ori e virgula dintre acolade
// ori virgula dintre valoare si cheie
if ( second_what(cuvinte[i+2]) == 2 ) {
// e virgula dintre valoare si cheie
bool ok = true;
unsigned int p = 0;
while ( p < hashTable.size() ) {
if ( hashTable[p].first.compare(cuvinte[i+1]) == 0 ) {
hashTable[p].second.push_back(cuvinte[i+3]);
ok = false;
break;
}
p ++;
}
if ( ok == true ) {
std :: vector <std :: string> array;
std :: pair < std :: string, std :: vector < std :: string > > prima_pereche;
prima_pereche.first = cuvinte[i+1];
// i+3 este valoarea
array.push_back(cuvinte[i+3]);
prima_pereche.second = array;
hashTable.push_back(prima_pereche);
}
i += 3;
} else {
// e cheia dintre acolade
}
}
/* if ( i > 0 && ( what(cuvinte[i]) == 1 || what(cuvinte[i]) == 2 ) ) {
// inseamna ca am prima cheie din pachet si i+2 este valoare
std :: vector <std :: string> array;
std :: pair < std :: string, std :: vector < std :: string > > prima_pereche;
prima_pereche.first = cuvinte[i];
// are sau nu are i+2 virgula sau doua puncte ??
if ( virgula(cuvinte[i+2]) == 2 && doua_puncte(cuvinte[i+2]) == 1 ) {
// valoarea este ok
array.push_back(cuvinte[i+2]);
prima_pereche.second = array;
hashTable.push_back(prima_pereche);
i += 2;
} else if ( virgula(cuvinte[i+2] == 2 ) {
// inseamna ca valoarea are la inceput 2 puncte
/*char *s;
cuvinte[i+2].copy(s,cuvinte[i+2]-
}
}
*/
i ++ ;
// g << cuvinte[i].size() << "++++++" << second_what(cuvinte[i]) << "----------" << cuvinte[i] << "------" << '\n';
}
unsigned int p = 0 ;
int size = hashTable.size() ;
for ( p = 0 ; p < size ; p ++ ) {
g << hashTable[p].first<< ',' ;
}
g << '\n' ;
for ( p = 0; p < hashTable[0].second.size() ; p ++ ) {
for ( unsigned int k = 0 ; k < size; k ++ ) {
g << hashTable[k].second[p] << ',' ;
}
g << '\n' ;
}
f.close ();
g.close ();
return 0;
}