/* * program: freq-C++.cc * auteur: felipe@ift2030 * date: 16/08/2002 * * objet: compter des frequences de mots en C++ et afficher les mots * rencontres par ordre decroissant de frequence. * * Utilisation des STL ici: * une hashmap associant un mot a sa frequence * un vecteur d'iterateur pour ensuite trier la hashmap avant * affichage (sinon sortie par ordre lexicographique) * * lire le fichier readme pour plus d'information * sur le format des entrees lues depuis l'entree standard * * A compiler avec: g++ -o freq-C++ freq-C++.cc * Exemple de lancement: cat corpus-1 | freq-C++ * */ #include #include #include // STL #include // STL #include // STL bool verbose = true; /* * structures de donnees STL */ struct ObjHash { hash H; // la fct de hachage size_t operator() (const string& s) const {return H(s.c_str());} // la fct de comparaison des cles bool operator() (const string& s1, const string& s2) const { return (strcmp(s1.c_str(), s2.c_str()) == 0) ; } }; typedef hash_map feHash; // la hashtable /* * Object function STL pour le tri * (tri sur la frequence, en cas d'egalite, tri sur la cle (le mot) */ struct feSort { bool operator()(const feHash::const_iterator& it1, const feHash::const_iterator& it2) const { return (it1->second > it2->second) || ((it1->second == it2->second) && (it1->first < it2->first)); } }; typedef vector feTrie; /* ------------------------------------------------------------------- main ------------------------------------------------------------------- */ int main(int argc, char *argv[]) { feHash frequences(50000); // la hashmap (50000 buckets a l'init) feTrie vec; // le vecteur qui va servir a trier les mots string line; int phrase=0,mot=0; // des compteurs feHash::iterator itf; // iterateur de travail /* * lecture des mots, un par un depuis stdin (cin) */ while (getline(cin,line)) if (line == "{sent}") phrase++; else { if ((itf = frequences.find(line)) == frequences.end()) frequences.insert(make_pair(line,1)); // nouveau mot -> freq=1 else itf->second++; // mot deja existant -> freq++ } /* * Tri de la hashmap (via un vecteur) */ for (feHash::const_iterator it=frequences.begin(); it != frequences.end(); it++) { mot += it->second; // cumul des frequences vec.push_back(it); } sort(vec.begin(),vec.end(),feSort()); /* * affichage des mots par ordre decroissant */ for (feTrie::const_iterator it=vec.begin(); it != vec.end(); it++) cout << (*it)->first << "\t\t" << (*it)->second << endl; /* * nb de lignes lues, de mots mots differents, etc */ if (verbose) cerr << "Phrases lues: " << phrase << " Mots lus: " << mot << " Mots differents: " << frequences.size() << endl; }