C++ map+count
velderama
Messages postés
199
Date d'inscription
Statut
Membre
Dernière intervention
-
sebsauvage Messages postés 32893 Date d'inscription Statut Modérateur Dernière intervention -
sebsauvage Messages postés 32893 Date d'inscription Statut Modérateur Dernière intervention -
Bonjour a tous,
j'ai une map map<string,int > mymap que j'ai rempli avec les mots d'un fichier et j'aimerai interdire l'enregistrement dans le map des mots qui ne sont pas uniques comme ceci :
map<string, int>::size_type size;
map<string,int > mymap;
{
while(getline(fichier,line)){
...
size=mymap.count(mot);
if(count>=1) mymap.erase(mot);
else mymap.insert(make_pair(mot,position));
...
}//fin while
}
toutefois j'ai des problemes pour le premier getline vu que il y'aura pas encore de mot dans le map et donc il enleverra les suivants mots identiques mais pas la premiere ligne ! comment dois-je faire?
merci d'avance
j'ai une map map<string,int > mymap que j'ai rempli avec les mots d'un fichier et j'aimerai interdire l'enregistrement dans le map des mots qui ne sont pas uniques comme ceci :
map<string, int>::size_type size;
map<string,int > mymap;
{
while(getline(fichier,line)){
...
size=mymap.count(mot);
if(count>=1) mymap.erase(mot);
else mymap.insert(make_pair(mot,position));
...
}//fin while
}
toutefois j'ai des problemes pour le premier getline vu que il y'aura pas encore de mot dans le map et donc il enleverra les suivants mots identiques mais pas la premiere ligne ! comment dois-je faire?
merci d'avance
A voir également:
- C++ map+count
- Google map satellite gratuit - Guide
- Telecharger carte google map - Guide
- Google map ma position - Guide
- Itinéraire google map entre deux adresses - Guide
- Historique trajet google map - Guide
3 réponses
J'ai vu dans la librairie un conteneur vector avec notamment une methode size qui me permettrait de faire le test suivant : si la taille est superieur a 1 alors de suprimmer le mot
map<string, vector<int> > mots;
string line;
int pos=0;
for(unsigned no_line = 0;std::getline(ifs,line);++no_line){
unsigned beg = 0;//debut mot
unsigned end = 1;//fin mot
for(unsigned no_mot=0;end < line.size();++no_mot){
for(;end < line.size() && !is_delim(line[end]);++end);
std::string mot(line,beg,end-beg);
pos=pos+beg;
if(mot.size()>=3 ){
mots.insert(make_pair(mot,pos));
}
beg = end + 1;
end = beg + 1;
}//for..line.size()
}
Puis je fais :---->
/*On enleve les mots "non uniques" */
map<string,vector<int> >::const_iterator
mots_it (mots.begin()),
mots_end(mots.end());
for(;mots_it!=mots_end;++mots_it){
const string & mot_cur = mots_it->first;
vector<int> & nbelement = mots_it->second;
if((nbelement.size())>1) mots.erase(mots_it);
}
ifs.close();
mais il y'a un bug :
invalid initialization of reference of type 'std::vector<int, std::allocator<int> >&' from expression of type 'const std::vector<int, std::allocator<int> >'
???
map<string, vector<int> > mots;
string line;
int pos=0;
for(unsigned no_line = 0;std::getline(ifs,line);++no_line){
unsigned beg = 0;//debut mot
unsigned end = 1;//fin mot
for(unsigned no_mot=0;end < line.size();++no_mot){
for(;end < line.size() && !is_delim(line[end]);++end);
std::string mot(line,beg,end-beg);
pos=pos+beg;
if(mot.size()>=3 ){
mots.insert(make_pair(mot,pos));
}
beg = end + 1;
end = beg + 1;
}//for..line.size()
}
Puis je fais :---->
/*On enleve les mots "non uniques" */
map<string,vector<int> >::const_iterator
mots_it (mots.begin()),
mots_end(mots.end());
for(;mots_it!=mots_end;++mots_it){
const string & mot_cur = mots_it->first;
vector<int> & nbelement = mots_it->second;
if((nbelement.size())>1) mots.erase(mots_it);
}
ifs.close();
mais il y'a un bug :
invalid initialization of reference of type 'std::vector<int, std::allocator<int> >&' from expression of type 'const std::vector<int, std::allocator<int> >'
???
Signification du message d'erreur
Ton erreur vient du fait que tu parcours mots avec un const_iterator (qui garantit que tu ne vas pas modifier les éléments sur lesquels tu itères). Or :
ne garantit pas la constance de ces éléments contrairement à un
Attention !!
Vu que tu utilises un erase tu ne peux donc pas utiliser un const_iterator car la map est modifiée. De plus, effacer un élément d'un std::map ou d'un std::set invalide les iterators donc même en virant les const ca ne marchera pas.
Correction du code ?
Au niveau du code je pense qu'il y a un vrai problème de compréhension au niveau de la ligne :
Si tu veux stocker les positions des mots de longueurs 3 ou plus :
Pour que tout le monde puisse t'aider il est important que tu mettes le code complet, si j'ai pu raccrocher c'est uniquement parce que j'ai répondu à ton précédent message. Par rapport à ça quand je mets des std:: ou des unsigned plutôt que des int c'est qu'il y a une raison, donc merci de les laisser :-)
Bonne chance
Ton erreur vient du fait que tu parcours mots avec un const_iterator (qui garantit que tu ne vas pas modifier les éléments sur lesquels tu itères). Or :
std::vector<int> & nbelement
ne garantit pas la constance de ces éléments contrairement à un
const std::vector<int> & nbelement
Attention !!
Vu que tu utilises un erase tu ne peux donc pas utiliser un const_iterator car la map est modifiée. De plus, effacer un élément d'un std::map ou d'un std::set invalide les iterators donc même en virant les const ca ne marchera pas.
Correction du code ?
Au niveau du code je pense qu'il y a un vrai problème de compréhension au niveau de la ligne :
mots.insert(make_pair(mot,pos));
Si tu veux stocker les positions des mots de longueurs 3 ou plus :
std::map<string, std::set<unsigned> > mots; std::string line; unsigned pos=0; for(unsigned no_line = 0;std::getline(ifs,line);++no_line){ unsigned beg = 0;//debut mot unsigned end = 1;//fin mot for(unsigned no_mot=0;end < line.size();++no_mot){ for(;end < line.size() && !is_delim(line[end]);++end); std::string mot(line,beg,end-beg); pos=pos+beg; if(mot.size()>=3 ){ mots[mot].insert(pos); } } }
Pour que tout le monde puisse t'aider il est important que tu mettes le code complet, si j'ai pu raccrocher c'est uniquement parce que j'ai répondu à ton précédent message. Par rapport à ça quand je mets des std:: ou des unsigned plutôt que des int c'est qu'il y a une raison, donc merci de les laisser :-)
Bonne chance
Ok, voila tout le code
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <set>
using namespace std;
inline bool is_delim(char c){
return !isalpha(c);
}
/***********************main**************************************/
int main(int argc, char *argv[]){
const char *filename = argv[1];
const char *filename2 = argv[2];
std::ifstream ifs(argv[1]);
std::ifstream if2s(argv[2]);
map<string, vector<int> > mots;
string line;
unsigned pos=0;
for(unsigned no_line = 0;std::getline(ifs,line);++no_line){
unsigned beg = 0;
unsigned end = 1;
for(unsigned no_mot=0;end < line.size();++no_mot){
for(;end < line.size() && !is_delim(line[end]);++end);
std::string mot(line,beg,end-beg);//recuperation du mot
pos=pos+beg;
if(mot.size()>=3 ){
std::cout << "\tajoute le mot[" << mot << "]position = "
<< pos << std::endl;
mots[mot].insert(pos);
}
beg = end + 1;
end = beg + 1;
}
}
/*On enleve les doublons*/
map<string,vector<int> >::iterator
mots_it (mots.begin()),
mots_end(mots.end());
for(;mots_it!=mots_end;++mots_it){
const std::string & mot_cur = mots_it->first;
vector<int> &nbelement = mots_it->second;
if((nbelement.size())>1) mots.erase(mots_it);
}
ifs.close();
return 0;
}//main
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <set>
using namespace std;
inline bool is_delim(char c){
return !isalpha(c);
}
/***********************main**************************************/
int main(int argc, char *argv[]){
const char *filename = argv[1];
const char *filename2 = argv[2];
std::ifstream ifs(argv[1]);
std::ifstream if2s(argv[2]);
map<string, vector<int> > mots;
string line;
unsigned pos=0;
for(unsigned no_line = 0;std::getline(ifs,line);++no_line){
unsigned beg = 0;
unsigned end = 1;
for(unsigned no_mot=0;end < line.size();++no_mot){
for(;end < line.size() && !is_delim(line[end]);++end);
std::string mot(line,beg,end-beg);//recuperation du mot
pos=pos+beg;
if(mot.size()>=3 ){
std::cout << "\tajoute le mot[" << mot << "]position = "
<< pos << std::endl;
mots[mot].insert(pos);
}
beg = end + 1;
end = beg + 1;
}
}
/*On enleve les doublons*/
map<string,vector<int> >::iterator
mots_it (mots.begin()),
mots_end(mots.end());
for(;mots_it!=mots_end;++mots_it){
const std::string & mot_cur = mots_it->first;
vector<int> &nbelement = mots_it->second;
if((nbelement.size())>1) mots.erase(mots_it);
}
ifs.close();
return 0;
}//main
EDIT : erf tu y es déjà ;) dsl