Cod sursa(job #1361758)

Utilizator codrut_grosuGrosu Codrut-Cristian codrut_grosu Data 25 februarie 2015 23:33:13
Problema Convertor Scor 50
Compilator cpp Status done
Runda rosedu_cdl_2015 Marime 12.34 kb
# 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;
}