/* * program: freq-C++.cc * auteur: felipe@ift6820 * date: 02/01/2005 * * 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 pour ensuite trier la hashmap avant * - affichage en ordre decroissant de frequence * * 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++ * * Note: you might have problems with * depending on your compiler version, if you do * but still want to compile it and try it, send * me an email, I will send you back a fix to that * (sometimes C++ is ridiculously complicated for nothing) * */ #include #include #include // STL #include // STL #include // STL #include // STL using namespace std; static bool verbose = true; /* */ struct ObjHash { // la fct de hachage size_t operator() (const string& s) const {return hash()(s.c_str());} }; typedef hash_map feHash; // la hashtable typedef vector > feTrie; // un vecteur pour trier les valeurs de la hashTable /* */ struct feSort { // fonction de tri sur la frequence, en cas d'egalite, tri sur la cle (le mot) inline bool operator()(const feHash::value_type & v1, const feHash::value_type & v2) const { return (v1.second > v2.second) || ((v1.second == v2.second) && (v1.first > v2.first)); } }; /* */ inline int sum(int sofar, const feHash::value_type& i) {return sofar + i.second;} namespace std { ostream& operator<< (ostream& out, const pair& v) { out << v.first << " " << v.second; return out; } } /* ------------------------------------------------------------------- main ------------------------------------------------------------------- */ int main(int argc, char *argv[]) { feHash frequences(50000); // la hashmap (50000 buckets a l'init) string line; int phrase=0; // nb de phrases rencontrees 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++ } /* * affichage des elts de la hash en ordre decroissant de frequence */ feTrie v(frequences.begin(),frequences.end()); // copie dans le vecteur sort(v.begin(),v.end(),feSort()); // trie selon l'ordre specifie par la fonction feSort copy(v.begin(),v.end(),ostream_iterator >(cout,"\n")); // affiche /* */ if (verbose) cerr << "Phrases lues: " << phrase << " Mots lus: " << accumulate(frequences.begin(),frequences.end(),0,sum) << " Mots differents: " << frequences.size() << endl; }