una saber que programa muestre minusculas minuscula mintomay mayusculas mayuscula letra hasta escribir convierte convertir contar como cadena abecedario c++ stl map

saber - mintomay c++



Haciendo que map:: find funcione sin distinguir entre mayúsculas y minúsculas (10)

Aquí hay algunas otras alternativas, incluida una que funciona significativamente más rápido.

#include <map> #include <string> #include <cstring> #include <iostream> #include <boost/algorithm/string.hpp> using std::string; using std::map; using std::cout; using std::endl; using namespace boost::algorithm; // recommended in Meyers, Effective STL when internationalization and embedded // NULLs aren''t an issue. Much faster than the STL or Boost lex versions. struct ciLessLibC : public std::binary_function<string, string, bool> { bool operator()(const string &lhs, const string &rhs) const { return strcasecmp(lhs.c_str(), rhs.c_str()) < 0 ; } }; // Modification of Manuel''s answer struct ciLessBoost : std::binary_function<std::string, std::string, bool> { bool operator() (const std::string & s1, const std::string & s2) const { return lexicographical_compare(s1, s2, is_iless()); } }; typedef map< string, int, ciLessLibC> mapLibc_t; typedef map< string, int, ciLessBoost> mapBoost_t; int main(void) { mapBoost_t cisMap; // change to test other comparitor cisMap["foo"] = 1; cisMap["FOO"] = 2; cisMap["bar"] = 3; cisMap["BAR"] = 4; cisMap["baz"] = 5; cisMap["BAZ"] = 6; cout << "foo == " << cisMap["foo"] << endl; cout << "bar == " << cisMap["bar"] << endl; cout << "baz == " << cisMap["baz"] << endl; return 0; }

¿El mapa :: encuentra el método de soporte de búsqueda insensible a mayúsculas y minúsculas?
Tengo un mapa de la siguiente manera

map<string,vector<string> > directory;

y quiere que la búsqueda a continuación ignore el caso.

directory.find(search_string);


El elemento Comparar de la plantilla de mapa tiene como valor predeterminado una clase de comparación binaria "menos". Mira la implementación:

http://www.cplusplus.com/reference/std/functional/less/

Es probable que pueda crear su propia clase que se deriva de binary_function (la clase principal a menos) y hacer la misma comparación sin mayúsculas y minúsculas.


En caso de que no desee tocar el tipo de mapa (para mantener su simplicidad y eficacia originales), pero no le moleste usar una función de búsqueda menos sensible a mayúsculas y minúsculas (O (N)):

string to_lower(string s) { transform(s.begin(), s.end(), s.begin(), (int(*)(int)) tolower ); return s; } typedef map<string, int> map_type; struct key_lcase_equal { string lcs; key_lcase_equal(const string& s) : lcs(to_lower(s)) {} bool operator()(const map_type::value_type& p) const { return to_lower(p.first) == lcs; } }; map_type::iterator find_ignore_case(map_type& m, const string& s) { return find_if(m.begin(), m.end(), key_lcase_equal(s)); }

PD: Tal vez fue idea de Roger Pate, pero no estoy seguro, ya que algunos detalles estaban un poco desajustados (std :: search ?, ¿comparador directo de cadenas?)


Implemente la función std :: less y compare cambiando ambas al mismo caso.


No por defecto. Deberá proporcionar un comparador personalizado como tercer argumento. El siguiente fragmento te ayudará ...

/************************************************************************/ /* Comparator for case-insensitive comparison in STL assos. containers */ /************************************************************************/ struct ci_less : std::binary_function<std::string, std::string, bool> { // case-independent (ci) compare_less binary function struct nocase_compare : public std::binary_function<unsigned char,unsigned char,bool> { bool operator() (const unsigned char& c1, const unsigned char& c2) const { return tolower (c1) < tolower (c2); } }; bool operator() (const std::string & s1, const std::string & s2) const { return std::lexicographical_compare (s1.begin (), s1.end (), // source range s2.begin (), s2.end (), // dest range nocase_compare ()); // comparison } };

Úselo como std::map< std::string, std::vector<std::string>, ci_less > myMap;

NOTA : std :: lexicographical_compare tiene algunos detalles esenciales. La comparación de cadenas no siempre es sencilla si se consideran configuraciones regionales. Vea this hilo en clc ++ si está interesado.

ACTUALIZACIÓN : Con C ++ 11 std::binary_function está en desuso y es innecesario ya que los tipos se deducen automáticamente.

struct ci_less { // case-independent (ci) compare_less binary function struct nocase_compare { bool operator() (const unsigned char& c1, const unsigned char& c2) const { return tolower (c1) < tolower (c2); } }; bool operator() (const std::string & s1, const std::string & s2) const { return std::lexicographical_compare (s1.begin (), s1.end (), // source range s2.begin (), s2.end (), // dest range nocase_compare ()); // comparison } };


No, no puedes hacer eso usando find ya que en ese caso habrá múltiples coincidencias. Por ejemplo, al insertar, le permite hacer algo como map["A"] = 1 y map["a"] = 2 y ahora si desea un caso insensible map.find("a") cuál es el valor de retorno esperado ? La forma más sencilla de resolver esto sería insertar la cadena en el mapa en un solo caso (ya sea en mayúscula o minúscula) y luego usar el mismo estuche al hacer el hallazgo.


Para C ++ 11 y más allá:

#include <strings.h> #include <map> #include <string> namespace detail { struct CaseInsensitiveComparator { bool operator()(const std::string& a, const std::string& b) const noexcept { return ::strcasecmp(a.c_str(), b.c_str()) < 0; } }; } // namespace detail template <typename T> using CaseInsensitiveMap = std::map<std::string, T, detail::CaseInsensitiveComparator>; int main(int argc, char* argv[]) { CaseInsensitiveMap<int> m; m["one"] = 1; std::cout << m.at("ONE") << "/n"; return 0; }


Probado:

template<typename T> struct ci_less:std::binary_function<T,T,bool> { bool operator() (const T& s1,const T& s2) const { return boost::ilexicographical_compare(s1,s2); }}; ... map<string,int,ci_less<string>> x=boost::assign::map_list_of ("One",1) ("Two",2) ("Three",3); cout << x["one"] << x["TWO"] <<x["thrEE"] << endl; //Output: 123


Puede instanciar std::map con tres parámetros: tipo de teclas, tipo de valores y función de comparación : un orden estricto y débil (esencialmente, una función o functor que se comporta como operator< en términos de transitividad y antirreflexión) de su gusto. Simplemente defina el tercer parámetro para hacer "insensible a mayúsculas y minúsculas menor que" (por ejemplo, con un < en las cadenas minúsculas que está comparando) y tendrá el "mapa insensible a mayúsculas y minúsculas" que desee.


Yo uso lo siguiente:

bool str_iless(std::string const & a, std::string const & b) { return boost::algorithm::lexicographical_compare(a, b, boost::is_iless()); } std::map<std::string, std::string, boost::function<bool(std::string const &, std::string const &)> > case_insensitive_map(&str_iless);