Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

replace_if && plusieurs conditions

5 réponses
Avatar
bcar
Bonjour,

Est-il possible de réduire ce code :
string field = ...;
replace( field.begin( ), field.end( ), '.', ' ' );
replace( field.begin( ), field.end( ), '*', ' ' );

en faisant quelque chose du genre :

replace_if( field.begin( ), field.end( ),
bind2nd( equal_to< char >(), '.' )
|| bind2nd( equal_to< char >(), '*' ),
' ' );

de manière a ne faire qu'un replace pour remplacer plusieurs
caractères à la fois

Par avance, merci

bcar

5 réponses

Avatar
Fabien LE LEZ
On Thu, 07 Jun 2007 12:50:39 +0200, bcar :

replace( field.begin( ), field.end( ), '.', ' ' );
replace( field.begin( ), field.end( ), '*', ' ' );


replace_if (field.begin( ), field.end( ), EstCaractereSpecial, ' ' );

avec

bool EstCaractereSpecial (char c)
{
return c == '.' || c == '*';
}

L'avantage, c'est que c'est nettement plus long que le code de départ
;-p

Avatar
bcar
bool EstCaractereSpecial (char c)
{
return c == '.' || c == '*';
}

L'avantage, c'est que c'est nettement plus long que le code de départ
;-p


D'accord et merci,

mais l'idée est plutôt de pouvoir mettre des variables à la place
de '.' et '*' et d'avoir potentiellement plus de 2 caractères différents

bcar

Avatar
Fabien LE LEZ
On Thu, 07 Jun 2007 14:39:44 +0200, bcar :

bool EstCaractereSpecial (char c)
{
return c == '.' || c == '*';
}


mais l'idée est plutôt de pouvoir mettre des variables à la place
de '.' et '*' et d'avoir potentiellement plus de 2 caractères différents


Il suffit alors de transformer EstCaractereSpecial en foncteur :

template <class Liste> class EstCaractereSpecial
{
public:
EstCaractereSpecial (Liste const& liste_caracteres_)
: liste_caracteres (liste_caracteres_)
{}

bool operator () (char c) const
{
return std::find (liste_caracteres.begin(),
liste_caracteres.end(), c) != liste_caracteres.end();
}

private:
Liste liste_caracteres;
};


replace_if (field.begin( ), field.end( ),
EstCaractereSpecial<std::string>("*."),
' ' );

Ou, si tu as plusieurs chaînes à traiter :

EstCaractereSpecial<std::string> est_asterisque_ou_point ("*.");

replace_if (field.begin( ), field.end( ),
est_asterisque_ou_point,
' ' );

replace_if (field2.begin( ), field2.end( ),
est_asterisque_ou_point,
' ' );


Ou encore :

std::vector<char> caracteres_a_virer;
caracteres_a_virer.push_back ('*');
caracteres_a_virer.push_back ('.');

replace_if (field.begin( ), field.end( ),
EstCaractereSpecial<std::vector<char> >(caracteres_a_virer),
' ' );

Bien sûr, tu peux créer une fonction pour t'éviter de saisir toi-même
le paramètre template :

template <class List> EstCaractereSpecial <Liste>
Cree_EstCaractereSpecial (Liste const& liste)
{
return liste;
}


replace_if (field.begin( ), field.end( ),
Cree_EstCaractereSpecial (caracteres_a_virer),
' ' );


Avatar
bcar
Il suffit alors de transformer EstCaractereSpecial en foncteur :

template <class Liste> class EstCaractereSpecial
{
public:
EstCaractereSpecial (Liste const& liste_caracteres_)
: liste_caracteres (liste_caracteres_)
{}

bool operator () (char c) const
{
return std::find (liste_caracteres.begin(),
liste_caracteres.end(), c) != liste_caracteres.end();
}

private:
Liste liste_caracteres;
};


replace_if (field.begin( ), field.end( ),
EstCaractereSpecial<std::string>("*."),
' ' );

Ou, si tu as plusieurs chaînes à traiter :



Merci encore, c'est exactement ce que je cherchais à faire.
j'étais finalement passé par
struct MyisEqualTo : std::binary_function< std::string, char, bool >
{
bool operator()( const std::string& s1, char c ) const
{
return std::find( s1.begin( ), s1.end( ), c ) != s1.end( );
}
};

std::string s1 = "*";
std::string s2 = "_";
std::replace_if( tr.begin( ), tr.end( ),
std::bind1st( myisEqualTo( ), s1 + s2 ),
'+' );

Il ne me reste plus qu'a transformer ma chaîne de recherche à la
volée et ce sera parfait (pour ça je préfère effectivement la
méthode que tu me propose).

bcar4

Avatar
James Kanze
On Jun 7, 1:42 pm, Fabien LE LEZ wrote:
On Thu, 07 Jun 2007 12:50:39 +0200, bcar :

replace( field.begin( ), field.end( ), '.', ' ' );
replace( field.begin( ), field.end( ), '*', ' ' );


replace_if (field.begin( ), field.end( ), EstCaractereSpecial, ' ' );

avec

bool EstCaractereSpecial (char c)
{
return c == '.' || c == '*';
}

L'avantage, c'est que c'est nettement plus long que le code de départ
;-p


Mais si la situation arrive souvent, en utilisant un tableau
variable, on ne l'écrit qu'une fois.

Dans mon propre code, mon type SetOfCharacter a une fonction qui
renvoie un tel objet prédicat, de façon à ce qu'on peut
écrire :

SetOfCharacter speciaux( ".*" ) ;
replace_if( field.begin(), field.end(), speciaux.contains(), '
' ) ;

Dans la pratique, je l'utilise souvent. Il m'a donc valu la
peine de développer la classe.

--
James Kanze (GABI Software) email:
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34