Hoofdletterongevoelige tekenreeksvergelijking in C++

Wat is de beste manier om hoofdletterongevoelige tekenreeksen in C++ te vergelijken zonder een tekenreeks om te zetten in hoofdletters of kleine letters?

Geef aan of de methoden Unicode-vriendelijk zijn en hoe draagbaar ze zijn.


Antwoord 1, autoriteit 100%

Boost bevat hiervoor een handig algoritme:

#include <boost/algorithm/string.hpp>
// Or, for fewer header dependencies:
//#include <boost/algorithm/string/predicate.hpp>
std::string str1 = "hello, world!";
std::string str2 = "HELLO, WORLD!";
if (boost::iequals(str1, str2))
{
    // Strings are identical
}

Antwoord 2, autoriteit 38%

Profiteer van de standaard char_traits. Bedenk dat een std::stringin feite een typedef is voor std::basic_string<char>, of meer expliciet, std::basic_string<char, std::char_traits<char> >. Het type char_traitsbeschrijft hoe karakters zich verhouden, hoe ze kopiëren, hoe ze casten enz. Het enige wat u hoeft te doen is een nieuwe string over basic_stringte typen en deze van uw eigen aangepaste char_traitsdie hoofdletters ongevoelig met elkaar vergelijken.

struct ci_char_traits : public char_traits<char> {
    static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
    static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
    static bool lt(char c1, char c2) { return toupper(c1) <  toupper(c2); }
    static int compare(const char* s1, const char* s2, size_t n) {
        while( n-- != 0 ) {
            if( toupper(*s1) < toupper(*s2) ) return -1;
            if( toupper(*s1) > toupper(*s2) ) return 1;
            ++s1; ++s2;
        }
        return 0;
    }
    static const char* find(const char* s, int n, char a) {
        while( n-- > 0 && toupper(*s) != toupper(a) ) {
            ++s;
        }
        return s;
    }
};
typedef std::basic_string<char, ci_char_traits> ci_string;

De details staan op goeroe van de week nummer 29.


Antwoord 3, autoriteit 31%

Het probleem met boost is dat je moet linken met en afhankelijk bent van boost. In sommige gevallen niet gemakkelijk (bijv. Android).

En het gebruik van char_traits betekent dat alje vergelijkingen niet hoofdlettergevoelig zijn, wat meestal niet is wat je wilt.

Dit zou voldoende moeten zijn. Het moet redelijk efficiënt zijn. Kan echter niet omgaan met unicode of iets dergelijks.

bool iequals(const string& a, const string& b)
{
    unsigned int sz = a.size();
    if (b.size() != sz)
        return false;
    for (unsigned int i = 0; i < sz; ++i)
        if (tolower(a[i]) != tolower(b[i]))
            return false;
    return true;
}

Update: Bonus C++14-versie (#include <algorithm>):

bool iequals(const string& a, const string& b)
{
    return std::equal(a.begin(), a.end(),
                      b.begin(), b.end(),
                      [](char a, char b) {
                          return tolower(a) == tolower(b);
                      });
}

Antwoord 4, autoriteit 18%

Als je een POSIX-systeem gebruikt, kun je strcasecmpgebruiken . Deze functie maakt echter geen deel uit van standaard C en is ook niet beschikbaar op Windows. Hiermee wordt een hoofdletterongevoelige vergelijking uitgevoerd op 8-bits tekens, zolang de landinstelling POSIX is. Als de landinstelling niet POSIX is, zijn de resultaten niet gedefinieerd (dus het kan een gelokaliseerde vergelijking zijn, of misschien niet). Een equivalent met brede tekens is niet beschikbaar.

Als dat niet lukt, hebben een groot aantal historische C-bibliotheekimplementaties de functies stricmp() en strnicmp(). Visual C++ op Windows heeft deze allemaal hernoemd door ze vooraf te laten gaan met een onderstrepingsteken omdat ze geen deel uitmaken van de ANSI-standaard, dus op dat systeem heten ze _stricmp of _strnicmp. Sommige bibliotheken kunnen ook functies hebben die equivalent zijn aan brede tekens of meerdere bytes (meestal genaamd wcsicmp, mbcsicmp enzovoort).

C en C++ zijn beide grotendeels onwetend over internationaliseringsproblemen, dus er is geen goede oplossing voor dit probleem, behalve om een bibliotheek van derden te gebruiken. Bekijk IBM ICU (International Components for Unicode)als je een robuuste bibliotheek voor C/C++ nodig hebt. ICU is voor zowel Windows- als Unix-systemen.


Antwoord 5, autoriteit 17%

Heb je het over een domme hoofdletterongevoelige vergelijking of een volledig genormaliseerde Unicode-vergelijking?

Een domme vergelijking zal geen strings vinden die misschien hetzelfde zijn, maar niet binair gelijk zijn.

Voorbeeld:

U212B (ANGSTROM SIGN)
U0041 (LATIN CAPITAL LETTER A) + U030A (COMBINING RING ABOVE)
U00C5 (LATIN CAPITAL LETTER A WITH RING ABOVE).

Zijn allemaal equivalent, maar ze hebben ook verschillende binaire representaties.

Dat gezegd hebbende, Unicode-normalisatiezou een verplichte lectuur moeten zijn, vooral als je van plan bent Hangul te ondersteunen, Thais en andere Aziatische talen.

Bovendien heeft IBM vrijwel de meeste geoptimaliseerde Unicode-algoritmen gepatenteerd en openbaar gemaakt. Ze onderhouden ook een implementatie: IBM ICU


Antwoord 6, autoriteit 10%

boost::iequals is niet utf-8-compatibel in het geval van string.
U kunt boost::localegebruiken.

comparator<char,collator_base::secondary> cmpr;
cout << (cmpr(str1, str2) ? "str1 < str2" : "str1 >= str2") << endl;
  • Primair — negeer accenten en hoofdletters, vergelijk alleen basisletters. “Facade” en “Façade” zijn bijvoorbeeld hetzelfde.
  • Secundair — negeer hoofdletters, maar houd rekening met accenten. “façade” en “façade” zijn verschillend, maar “Façade” en “façade” zijn hetzelfde.
  • Tertiair — houd rekening met zowel hoofdletters als accenten: “Façade” en “Façade” zijn verschillend. Negeer interpunctie.
  • Kwartair — denk aan alle hoofdletters, accenten en leestekens. De woorden moeten identiek zijn in termen van Unicode-representatie.
  • Identiek — als quaternair, maar vergelijk ook codepunten.

Antwoord 7, autoriteit 10%

Mijn eerste gedachte voor een niet-unicode-versie was om zoiets als dit te doen:

bool caseInsensitiveStringCompare(const string& str1, const string& str2) {
    if (str1.size() != str2.size()) {
        return false;
    }
    for (string::const_iterator c1 = str1.begin(), c2 = str2.begin(); c1 != str1.end(); ++c1, ++c2) {
        if (tolower(static_cast<unsigned char>(*c1)) != tolower(static_cast<unsigned char>(*c2))) {
            return false;
        }
    }
    return true;
}

Antwoord 8, autoriteit 7%

Je kunt strcasecmpgebruiken op Unix, of stricmpop Windows.

Eén ding dat tot nu toe niet is genoemd, is dat als je stl-strings gebruikt met deze methoden, het handig is om eerst de lengte van de twee strings te vergelijken, aangezien deze informatie al voor je beschikbaar is in de stringklasse. Dit zou de dure stringvergelijking kunnen voorkomen als de twee strings die u vergelijkt in de eerste plaats niet eens dezelfde lengte hebben.


Antwoord 9, autoriteit 5%

Ik probeer een goed antwoord uit alle berichten te verzamelen, dus help me dit te bewerken:

Hier is een methode om dit te doen, hoewel het de strings transformeert, en niet Unicode-vriendelijk is, zou het draagbaar moeten zijn, wat een pluspunt is:

bool caseInsensitiveStringCompare( const std::string& str1, const std::string& str2 ) {
    std::string str1Cpy( str1 );
    std::string str2Cpy( str2 );
    std::transform( str1Cpy.begin(), str1Cpy.end(), str1Cpy.begin(), ::tolower );
    std::transform( str2Cpy.begin(), str2Cpy.end(), str2Cpy.begin(), ::tolower );
    return ( str1Cpy == str2Cpy );
}

Van wat ik heb gelezen, is dit draagbaarder dan stricmp() omdat stricmp() in feite geen deel uitmaakt van de std-bibliotheek, maar alleen wordt geïmplementeerd door de meeste compilerleveranciers.

Om een echt Unicode-vriendelijke implementatie te krijgen, lijkt het erop dat je buiten de std-bibliotheek moet gaan. Een goede bibliotheek van derden is de IBM ICU (International Components for Unicode)

Ook boost::iequalsbiedt een redelijk goede tool om dit soort vergelijkingen uit te voeren.


Antwoord 10, autoriteit 4%

Visuele C++-tekenreeksfuncties die unicode ondersteunen: http://msdn.microsoft.com /nl-nl/bibliotheek/cc194799.aspx

degene die u waarschijnlijk zoekt is _wcsnicmp


Antwoord 11, autoriteit 4%

Ter informatie, strcmp()en stricmp()zijn kwetsbaar voor bufferoverloop, omdat ze gewoon verwerken totdat ze een nul-terminator bereiken. Het is veiliger om _strncmp()en _strnicmp().


Antwoord 12, autoriteit 4%

str1.size() == str2.size() && std::equal(str1.begin(), str1.end(), str2.begin(), [](auto a, auto b){return std::tolower(a)==std::tolower(b);})

Je kunt de bovenstaande code gebruiken in C++14 als je niet in staat bent om boost te gebruiken. Je moet std::towlowergebruiken voor brede tekens.


Antwoord 13, autoriteit 4%

Zie std::lexicographical_compare:

// lexicographical_compare example
#include <iostream>  // std::cout, std::boolalpha
#include <algorithm>  // std::lexicographical_compare
#include <cctype>  // std::tolower
// a case-insensitive comparison function:
bool mycomp (char c1, char c2) {
    return std::tolower(c1) < std::tolower(c2);
}
int main () {
    char foo[] = "Apple";
    char bar[] = "apartment";
    std::cout << std::boolalpha;
    std::cout << "Comparing foo and bar lexicographically (foo < bar):\n";
    std::cout << "Using default comparison (operator<): ";
    std::cout << std::lexicographical_compare(foo, foo + 5, bar, bar + 9);
    std::cout << '\n';
    std::cout << "Using mycomp as comparison object: ";
    std::cout << std::lexicographical_compare(foo, foo + 5, bar, bar + 9, mycomp);
    std::cout << '\n';
    return 0;
}

Demo


Antwoord 14, autoriteit 3%

De Boost.Stringbibliotheek heeft veel van algoritmen voor het maken van vergelijkingen zonder hoofdletters, enzovoort.

Je zou je eigen kunnen implementeren, maar waarom zou je je druk maken als het al is gedaan?


Antwoord 15, autoriteit 3%

Kort en leuk. Geen andere afhankelijkheden, dan uitgebreidestd C lib.

strcasecmp(str1.c_str(), str2.c_str()) == 0

retourneert trueals str1en str2gelijk zijn.
strcasecmpbestaat mogelijk niet, er kunnen analogen zijn stricmp, strcmpi, enz.

Voorbeeldcode:

#include <iostream>
#include <string>
#include <string.h> //For strcasecmp(). Also could be found in <mem.h>
using namespace std;
/// Simple wrapper
inline bool str_ignoreCase_cmp(std::string const& s1, std::string const& s2) {
    if(s1.length() != s2.length())
        return false;  // optimization since std::string holds length in variable.
    return strcasecmp(s1.c_str(), s2.c_str()) == 0;
}
/// Function object - comparator
struct StringCaseInsensetiveCompare {
    bool operator()(std::string const& s1, std::string const& s2) {
        if(s1.length() != s2.length())
            return false;  // optimization since std::string holds length in variable.
        return strcasecmp(s1.c_str(), s2.c_str()) == 0;
    }
    bool operator()(const char *s1, const char * s2){ 
        return strcasecmp(s1,s2)==0;
    }
};
/// Convert bool to string
inline char const* bool2str(bool b){ return b?"true":"false"; }
int main()
{
    cout<< bool2str(strcasecmp("asd","AsD")==0) <<endl;
    cout<< bool2str(strcasecmp(string{"aasd"}.c_str(),string{"AasD"}.c_str())==0) <<endl;
    StringCaseInsensetiveCompare cmp;
    cout<< bool2str(cmp("A","a")) <<endl;
    cout<< bool2str(cmp(string{"Aaaa"},string{"aaaA"})) <<endl;
    cout<< bool2str(str_ignoreCase_cmp(string{"Aaaa"},string{"aaaA"})) <<endl;
    return 0;
}

Uitvoer:

true
true
true
true
true

Antwoord 16, autoriteit 3%

Voor mijn basis hoofdletterongevoelige tekenreeksvergelijkingsbehoeften heb ik liever geen externe bibliotheek te gebruiken, noch wil ik een aparte tekenreeksklasse met hoofdletterongevoelige eigenschappen die incompatibel is met al mijn andere tekenreeksen.

Dus wat ik heb bedacht is dit:

bool icasecmp(const string& l, const string& r)
{
    return l.size() == r.size()
        && equal(l.cbegin(), l.cend(), r.cbegin(),
            [](string::value_type l1, string::value_type r1)
                { return toupper(l1) == toupper(r1); });
}
bool icasecmp(const wstring& l, const wstring& r)
{
    return l.size() == r.size()
        && equal(l.cbegin(), l.cend(), r.cbegin(),
            [](wstring::value_type l1, wstring::value_type r1)
                { return towupper(l1) == towupper(r1); });
}

Een eenvoudige functie met één overbelasting voor char en een andere voor whar_t. Gebruikt niets dat niet-standaard is, dus zou op elk platform goed moeten zijn.

De gelijkheidsvergelijking houdt geen rekening met problemen zoals codering van variabele lengte en Unicode-normalisatie, maar basic_string heeft daar geen ondersteuning voor die ik sowieso al weet en het is normaal gesproken geen probleem.

In gevallen waar meer geavanceerde lexicografische manipulatie van tekst vereist is, moet je gewoon een externe bibliotheek zoals Boost gebruiken, wat te verwachten is.


Antwoord 17, autoriteit 2%

Dit doen zonder Boost te gebruiken kan worden gedaan door de C-tekenreeksaanwijzer op te halen met c_str()en strcasecmpte gebruiken:

std::string str1 ="aBcD";
std::string str2 = "AbCd";;
if (strcasecmp(str1.c_str(), str2.c_str()) == 0)
{
    //case insensitive equal 
}

Antwoord 18, autoriteit 2%

Ervan uitgaande dat u op zoek bent naar een methode en niet naar een magische functie die al bestaat, is er eerlijk gezegd geen betere manier. We zouden allemaal codefragmenten kunnen schrijven met slimme trucs voor beperkte tekensets, maar uiteindelijk moet je op een gegeven moment de tekens converteren.

De beste aanpak voor deze conversie is om dit voorafgaand aan de vergelijking te doen. Dit geeft je veel flexibiliteit als het gaat om coderingsschema’s, waar je eigenlijke vergelijkingsoperator niets van af zou moeten weten.

Je kunt deze conversie natuurlijk ‘verbergen’ achter je eigen tekenreeksfunctie of -klasse, maar je moet de tekenreeksen nog steeds converteren voordat je kunt vergelijken.


Antwoord 19, autoriteit 2%

Ik heb een hoofdletterongevoelige versie van char_traits geschreven voor gebruik met std::basic_string om een std::string te genereren die niet hoofdlettergevoelig is bij het doen van vergelijkingen, zoekopdrachten, enz. met behulp van de ingebouwde std::basic_string ledenfuncties.

Dus met andere woorden, ik wilde zoiets doen.

std::string a = "Hello, World!";
std::string b = "hello, world!";
assert( a == b );

…die std::string niet aankan. Hier is het gebruik van mijn nieuwe char_traits:

std::istring a = "Hello, World!";
std::istring b = "hello, world!";
assert( a == b );

…en hier is de implementatie:

/*  ---
        Case-Insensitive char_traits for std::string's
        Use:
            To declare a std::string which preserves case but ignores case in comparisons & search,
            use the following syntax:
                std::basic_string<char, char_traits_nocase<char> > noCaseString;
            A typedef is declared below which simplifies this use for chars:
                typedef std::basic_string<char, char_traits_nocase<char> > istring;
    --- */
    template<class C>
    struct char_traits_nocase : public std::char_traits<C>
    {
        static bool eq( const C& c1, const C& c2 )
        { 
            return ::toupper(c1) == ::toupper(c2); 
        }
        static bool lt( const C& c1, const C& c2 )
        { 
            return ::toupper(c1) < ::toupper(c2);
        }
        static int compare( const C* s1, const C* s2, size_t N )
        {
            return _strnicmp(s1, s2, N);
        }
        static const char* find( const C* s, size_t N, const C& a )
        {
            for( size_t i=0 ; i<N ; ++i )
            {
                if( ::toupper(s[i]) == ::toupper(a) ) 
                    return s+i ;
            }
            return 0 ;
        }
        static bool eq_int_type( const int_type& c1, const int_type& c2 )
        { 
            return ::toupper(c1) == ::toupper(c2) ; 
        }       
    };
    template<>
    struct char_traits_nocase<wchar_t> : public std::char_traits<wchar_t>
    {
        static bool eq( const wchar_t& c1, const wchar_t& c2 )
        { 
            return ::towupper(c1) == ::towupper(c2); 
        }
        static bool lt( const wchar_t& c1, const wchar_t& c2 )
        { 
            return ::towupper(c1) < ::towupper(c2);
        }
        static int compare( const wchar_t* s1, const wchar_t* s2, size_t N )
        {
            return _wcsnicmp(s1, s2, N);
        }
        static const wchar_t* find( const wchar_t* s, size_t N, const wchar_t& a )
        {
            for( size_t i=0 ; i<N ; ++i )
            {
                if( ::towupper(s[i]) == ::towupper(a) ) 
                    return s+i ;
            }
            return 0 ;
        }
        static bool eq_int_type( const int_type& c1, const int_type& c2 )
        { 
            return ::towupper(c1) == ::towupper(c2) ; 
        }       
    };
    typedef std::basic_string<char, char_traits_nocase<char> > istring;
    typedef std::basic_string<wchar_t, char_traits_nocase<wchar_t> > iwstring;

Antwoord 20

Ik heb goede ervaring met het gebruik van de International Components for Unicode-bibliotheken– ze zijn buitengewoon krachtig, en bieden methoden voor conversie, locale-ondersteuning, datum- en tijdweergave, case-mapping (wat u niet lijkt te willen), en sortering, inclusief hoofdletter- en accentongevoelige vergelijking (en meer). Ik heb alleen de C++-versie van de bibliotheken gebruikt, maar ze lijken ook een Java-versie te hebben.

Er bestaan methoden om genormaliseerde vergelijkingen uit te voeren zoals bedoeld door @Coincoin, en kunnen zelfs rekening houden met locale – bijvoorbeeld (en dit is een sorteervoorbeeld, niet strikt gelijkheid), traditioneel in het Spaans (in Spanje), de lettercombinatie “ll ” sorteert tussen “l” en “m”, dus “lz” < “ll” < “ma”.


Antwoord 21

Gebruik gewoon strcmp()voor hoofdlettergevoelig en strcmpi()of stricmp()voor hoofdletterongevoelige vergelijking. Die beide in het headerbestand <string.h>

. staan

indeling:

int strcmp(const char*,const char*);    //for case sensitive
int strcmpi(const char*,const char*);   //for case insensitive

Gebruik:

string a="apple",b="ApPlE",c="ball";
if(strcmpi(a.c_str(),b.c_str())==0)      //(if it is a match it will return 0)
    cout<<a<<" and "<<b<<" are the same"<<"\n";
if(strcmpi(a.c_str(),b.c_str()<0)
    cout<<a[0]<<" comes before ball "<<b[0]<<", so "<<a<<" comes before "<<b;

Uitvoer

appel en ApPlE zijn hetzelfde

a komt voor b, dus appel komt voor bal


Antwoord 22

Laat op het feest, maar hier is een variant die std::localegebruikt, en dus correct omgaat met Turks:

auto tolower = std::bind1st(
    std::mem_fun(
        &std::ctype<char>::tolower),
    &std::use_facet<std::ctype<char> >(
        std::locale()));

geeft u een functor die de actieve landinstelling gebruikt om tekens naar kleine letters te converteren, die u vervolgens via std::transformkunt gebruiken om tekenreeksen in kleine letters te genereren:

std::string left = "fOo";
transform(left.begin(), left.end(), left.begin(), tolower);

Dit werkt ook voor op wchar_tgebaseerde strings.


Antwoord 23

Even een opmerking over welke methode je uiteindelijk ook kiest, als die methode het gebruik van strcmpbevat dat sommige antwoorden suggereren:

strcmpwerkt in het algemeen niet met Unicode-gegevens. Over het algemeen werkt het zelfs niet met byte-gebaseerde Unicode-coderingen, zoals utf-8, omdat strcmpalleen byte-per-byte vergelijkingen maakt en Unicode-codepunten die in utf-8 zijn gecodeerd, kunnen meer dan 1 byte. De enige specifieke Unicode-case die strcmpcorrect afhandelt, is wanneer een tekenreeks die is gecodeerd met een byte-gebaseerde codering alleen codepunten onder U+00FF bevat – dan is de byte-per-byte-vergelijking voldoende.


Antwoord 24

Sinds begin 2013 is het ICU-project, dat wordt onderhouden door IBM, hier een redelijk goed antwoord op.

http://site.icu-project.org/

ICU is een “complete, draagbare Unicode-bibliotheek die de industriestandaarden nauwgezet volgt.” Voor het specifieke probleem van stringvergelijking doet het Collation-object wat je wilt.

Het Mozilla-project nam medio 2012 ICU over voor internationalisering in Firefox; u kunt de technische discussie volgen, inclusief problemen met buildsystemen en gegevensbestandsgrootte, hier:


Antwoord 25

Het lijkt erop dat bovenstaande oplossingen de vergelijkingsmethode niet gebruiken en totaal niet opnieuw implementeren, dus hier is mijn oplossing en ik hoop dat deze voor u werkt (het werkt prima).

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
string tolow(string a)
{
    for(unsigned int i=0;i<a.length();i++)
    {
        a[i]=tolower(a[i]);
    }
    return a;
}
int main()
{
    string str1,str2;
    cin>>str1>>str2;
    int temp=tolow(str1).compare(tolow(str2));
    if(temp>0)
        cout<<1;
    else if(temp==0)
        cout<<0;
    else
        cout<<-1;
}

Antwoord 26

Een eenvoudige manier om twee strings in c++ te vergelijken (getest voor Windows) is het gebruik van _stricmp

// Case insensitive (could use equivalent _stricmp)  
result = _stricmp( string1, string2 );  

Als u wilt gebruiken met std::string, een voorbeeld:

std::string s1 = string("Hello");
if ( _stricmp(s1.c_str(), "HELLO") == 0)
   std::cout << "The string are equals.";

Voor meer informatie hier: https://msdn.microsoft.com/ it-it/library/e0z9k731.aspx


Antwoord 27

Als je Boost-bibliotheekniet wilt gebruiken, dan is hier een oplossing voor met alleen de C++ standaard io-header.

#include <iostream>
struct iequal
{
    bool operator()(int c1, int c2) const
    {
        // case insensitive comparison of two characters.
        return std::toupper(c1) == std::toupper(c2);
    }
};
bool iequals(const std::string& str1, const std::string& str2)
{
    // use std::equal() to compare range of characters using the functor above.
    return std::equal(str1.begin(), str1.end(), str2.begin(), iequal());
}
int main(void)
{
    std::string str_1 = "HELLO";
    std::string str_2 = "hello";
    if(iequals(str_1,str_2))
    {
        std::cout<<"String are equal"<<std::endl;   
    }
    else
    {
        std::cout<<"String are not equal"<<std::endl;
    }
    return 0;
}

Antwoord 28

Als je een bronstring vaker moet vergelijken met andere strings, is een elegante oplossing om regex te gebruiken.

std::wstring first = L"Test";
std::wstring second = L"TEST";
std::wregex pattern(first, std::wregex::icase);
bool isEqual = std::regex_match(second, pattern);

Antwoord 29

bool insensitive_c_compare(char A, char B){
  static char mid_c = ('Z' + 'a') / 2 + 'Z';
  static char up2lo = 'A' - 'a'; /// the offset between upper and lowers
  if ('a' >= A and A >= 'z' or 'A' >= A and 'Z' >= A)
      if ('a' >= B and B >= 'z' or 'A' >= B and 'Z' >= B)
      /// check that the character is infact a letter
      /// (trying to turn a 3 into an E would not be pretty!)
      {
        if (A > mid_c and B > mid_c or A < mid_c and B < mid_c)
        {
          return A == B;
        }
        else
        {
          if (A > mid_c)
            A = A - 'a' + 'A'; 
          if (B > mid_c)/// convert all uppercase letters to a lowercase ones
            B = B - 'a' + 'A';
          /// this could be changed to B = B + up2lo;
          return A == B;
        }
      }
}

dit zou waarschijnlijk veel efficiënter kunnen, maar hier is een omvangrijke versie met al zijn stukjes kaal.

niet zo draagbaar, maar werkt goed met alles wat op mijn computer staat (geen idee, ik ben van afbeeldingen en niet van woorden)


Antwoord 30

Een gemakkelijke manier om strings te vergelijken die alleen verschillen door kleine letters en hoofdletters, is door een ascii-vergelijking uit te voeren. Alle hoofdletters en kleine letters verschillen 32 bits in de ascii-tabel, met behulp van deze informatie hebben we het volgende…

   for( int i = 0; i < string2.length(); i++)
    {
       if (string1[i] == string2[i] || int(string1[i]) == int(string2[j])+32 ||int(string1[i]) == int(string2[i])-32) 
    {
      count++;
      continue;
    }
    else 
    {
      break;
    }
    if(count == string2.length())
    {
      //then we have a match
    }
}

Other episodes