1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
#include <algorithm>
#include <sstream>
#include <set>
#include <map>
#include <string>
#include <fstream>
#include <iterator>
#include <iostream>
using namespace std;
// Outil de traitement de mots qui retire les séparateurs
struct RetireSeparateurs
{
string Traiter( string const & mot, string const & separateurs ) const
{
string motRetour( mot );
// Pour chaque lettre du mot
for ( size_t i = 0; i < motRetour.size(); ++i )
{
// La lettre est un séparateur
if ( separateurs.find( motRetour[i] ) != string::npos )
{
motRetour.erase( i );
--i;
}
}
return motRetour;
}
};
// Prédicat indiquant si un mot répond au critère : plus de trois caractère
struct PlusDeTroisCaracteres
{
bool Verifier( string const & mot ) const
{
return mot.size() > 3;
}
};
// Foncteur qui, à partir d'un mot, remplit la map et le set
template <typename TRAITEMENT,
typename CRITEREAJOUT>
struct Remplir
{
Remplir( map<string, int> & tousLesMots,
set<string> & doublons,
string const & sep )
: m_map( tousLesMots ),
m_set( doublons ),
m_sep( sep ),
m_pos( 0 )
{
}
template <typename T>
void operator() ( T const & constmot )
{
// Obtient un nouveau mot débarassé des séparateurs
string mot( TRAITEMENT().Traiter( constmot, m_sep ) );
// Un séparateur isolé ?
if ( mot.empty() )
return;
// Le mot est bien réél, on incrémente la position
++m_pos;
// Le mot répond-t-il aux critères ?
if ( !CRITEREAJOUT().Verifier( mot ) )
return;
// Le mot existe-t-il déjà ?
if ( m_map.find( mot ) != m_map.end() )
// Un doublon détecté
m_set.insert( mot );
else
// Un nouveau mot, on stocke sa position
m_map[ mot ] = m_pos;
}
private:
map<string, int> & m_map;
set<string> & m_set;
string const & m_sep;
int m_pos;
};
// Foncteur qui supprime un mot d'une map
struct Supprimer
{
Supprimer( map<string, int> & tousLesMots )
: m_map( tousLesMots )
{
}
template <typename T>
void operator() ( T const & mot ) const
{
m_map.erase( mot );
}
private:
map<string, int> & m_map;
};
int main(int argc, char *argv[1])
{
// Ouverture du bon fichier
ifstream file;
file.open(argv[1], ios::in);
// Map qui va au FINAL contenir les mots uniques
// de plus de 3 carac avec leur position
map<string, int> motsUniques;
// Set intermédiaire des mots doublons
// Sert à retirer (après coup) les doublons de la map
set<string> doublons;
// Chaine contenant les caractère a ne pas prendre en compte
// On pourrait plutot utiliser un Set pour plus de rapidité
string separateurs("()[].,'");
// Itere chaque "mot" du fichier
// (séparés par des espaces ou des sauts de ligne)
// Insère les mots dans la map selon un critère
// après traitement préalable et trouve les doublons
for_each( istream_iterator<string>(file), istream_iterator<string>(),
Remplir<RetireSeparateurs,PlusDeTroisCaracteres>( motsUniques, doublons, separateurs ) );
// Supprime de la map les doublons contenus dans le Set
for_each( doublons.begin(), doublons.end(),
Supprimer( motsUniques ) );
// Ecriture du résultat
ofstream outfile;
outfile.open( "D:\\Projet2008\\Dev-Cpp\\Projet\\out.txt" , ios::out);
for ( map<string, int>::iterator it = motsUniques.begin(); it != motsUniques.end(); ++it )
outfile << it->first << " " << it->second << endl;
return 0;
} |
Partager