C++ map+count
Fermé
velderama
Messages postés
199
Date d'inscription
mardi 26 février 2008
Statut
Membre
Dernière intervention
11 mai 2011
-
5 mars 2008 à 10:56
sebsauvage Messages postés 32847 Date d'inscription mercredi 29 août 2001 Statut Modérateur Dernière intervention 21 octobre 2019 - 6 mars 2008 à 17:26
sebsauvage Messages postés 32847 Date d'inscription mercredi 29 août 2001 Statut Modérateur Dernière intervention 21 octobre 2019 - 6 mars 2008 à 17:26
A voir également:
- C++ map+count
- Google map satellite - Guide
- Telecharger carte google map - Guide
- Select count * ✓ - Forum Webmastering
- Google map - Télécharger - Transports & Cartes
- Coordonnées gps google map - Guide
3 réponses
velderama
Messages postés
199
Date d'inscription
mardi 26 février 2008
Statut
Membre
Dernière intervention
11 mai 2011
10
5 mars 2008 à 14:27
5 mars 2008 à 14:27
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> >'
???
mamiemando
Messages postés
32283
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
17 mars 2023
7 572
5 mars 2008 à 17:17
5 mars 2008 à 17:17
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
velderama
Messages postés
199
Date d'inscription
mardi 26 février 2008
Statut
Membre
Dernière intervention
11 mai 2011
10
6 mars 2008 à 10:36
6 mars 2008 à 10:36
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
sebsauvage
Messages postés
32847
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 656
6 mars 2008 à 17:20
6 mars 2008 à 17:20
Et pourquoi pas plutôt une hashtable ? (aussi parfois appellé dictionnaire).
Elle assure l'unicité des éléments.
(Je ne sais plus comment elle s'appelle en STL...)
Elle assure l'unicité des éléments.
(Je ne sais plus comment elle s'appelle en STL...)
velderama
Messages postés
199
Date d'inscription
mardi 26 février 2008
Statut
Membre
Dernière intervention
11 mai 2011
10
6 mars 2008 à 17:25
6 mars 2008 à 17:25
c'est map il me semble l'equivalent du hashtable en c++
sebsauvage
Messages postés
32847
Date d'inscription
mercredi 29 août 2001
Statut
Modérateur
Dernière intervention
21 octobre 2019
15 656
>
velderama
Messages postés
199
Date d'inscription
mardi 26 février 2008
Statut
Membre
Dernière intervention
11 mai 2011
6 mars 2008 à 17:26
6 mars 2008 à 17:26
ah pardon j'avais lu trop vite, oui tu as utilisé map.
5 mars 2008 à 14:40
EDIT : erf tu y es déjà ;) dsl