문제

문자열을 모두 대문자 또는 모두 소문자로 변환하지 않고 C++에서 대소문자를 구분하지 않는 문자열 비교를 수행하는 가장 좋은 방법은 무엇입니까?

메소드가 유니코드 친화적인지, 이식성이 얼마나 좋은지 표시해 주세요.

도움이 되었습니까?

해결책

Boost에는 이를 위한 편리한 알고리즘이 포함되어 있습니다.

#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
}

다른 팁

표준을 활용하세요 char_traits.다음을 기억하세요. std::string 실제로는 typedef입니다. std::basic_string<char>, 또는 더 명시적으로, std::basic_string<char, std::char_traits<char> >.그만큼 char_traits 유형은 문자 비교 방법, 복사 방법, 캐스팅 방법 등을 설명합니다.당신이 해야 할 일은 새로운 문자열을 typedef하는 것 뿐입니다. basic_string, 사용자 정의로 제공 char_traits 대소문자를 구분하지 않고 비교합니다.

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;

자세한 내용은 금주의 전문가 29위.

부스트의 문제점은 부스트와 연결하고 이에 의존해야 한다는 것입니다.어떤 경우에는 쉽지 않습니다(예:기계적 인조 인간).

char_traits를 사용하는 것은 의미합니다. 모두 비교에서는 대소문자를 구분하지 않으므로 일반적으로 원하는 바가 아닙니다.

이것으로 충분합니다.합리적으로 효율적이어야 합니다.하지만 유니코드 등은 처리하지 않습니다.

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;
}

업데이트:보너스 C++14 버전(#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);
                      });
}

POSIX 시스템을 사용하는 경우 다음을 사용할 수 있습니다. strcasecmp.하지만 이 기능은 표준 C의 일부가 아니며 Windows에서도 사용할 수 없습니다.로케일이 POSIX인 경우 8비트 문자에 대해 대소문자를 구분하지 않는 비교를 수행합니다.로케일이 POSIX가 아닌 경우 결과는 정의되지 않습니다(따라서 지역화된 비교를 수행할 수도 있고 그렇지 않을 수도 있음).와이드 문자에 해당하는 문자는 사용할 수 없습니다.

이것이 실패하면 많은 역사적 C 라이브러리 구현에는 stricmp() 및 strnicmp() 함수가 있습니다.Windows의 Visual C++는 ANSI 표준의 일부가 아니기 때문에 밑줄을 접두어로 붙여 이름을 모두 변경했습니다. 따라서 해당 시스템에서는 호출됩니다. _stricmp 또는 _strnicmp.일부 라이브러리에는 와이드 문자 또는 멀티바이트에 해당하는 함수(일반적으로 이름이 지정됨)가 있을 수도 있습니다.wcsicmp, mbcsicmp 등).

C와 C++는 모두 국제화 문제에 대해 거의 무지하므로 타사 라이브러리를 사용하는 것 외에는 이 문제에 대한 좋은 해결책이 없습니다.확인해 보세요 IBM ICU(유니코드용 국제 구성 요소) C/C++용 강력한 라이브러리가 필요한 경우.ICU는 Windows 및 Unix 시스템 모두에 사용됩니다.

대소문자를 구분하지 않는 멍청한 비교 또는 완전 정규화된 유니코드 비교에 대해 이야기하고 있습니까?

멍청한 비교는 동일할 수 있지만 이진 동일하지 않은 문자열을 찾지 않습니다.

예:

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

모두 동일하지만 이진 표현도 다릅니다.

즉, 유니코드 정규화 특히 한글, 태국어 및 기타 아시아 언어를 지원하려는 경우 반드시 읽어야 합니다.

또한 IBM은 가장 최적화된 유니코드 알고리즘에 대한 특허를 거의 취득하여 공개적으로 사용할 수 있도록 했습니다.또한 구현을 유지합니다. IBM ICU

Boost::iequals는 문자열의 경우 utf-8과 호환되지 않습니다.당신이 사용할 수있는 부스트::로케일.

comparator<char,collator_base::secondary> cmpr;
cout << (cmpr(str1, str2) ? "str1 < str2" : "str1 >= str2") << endl;
  • 기본 - 악센트와 대소문자를 무시하고 기본 문자만 비교합니다.예를 들어 "facade"와 "Façade"는 동일합니다.
  • 보조 - 대소문자는 무시하지만 악센트는 고려합니다."facade"와 "façade"는 다르지만 "Façade"와 "façade"는 동일합니다.
  • 3차 - 대소문자와 악센트를 모두 고려합니다."파사드"와 "파사드"는 다릅니다.구두점을 무시합니다.
  • 4차 -- 모든 대소문자, 악센트 및 구두점을 고려합니다.단어는 유니코드 표현 측면에서 동일해야 합니다.
  • 동일합니다. 4차와 동일하지만 코드 포인트도 비교합니다.

유니코드가 아닌 버전에 대한 나의 첫 번째 생각은 다음과 같은 작업을 수행하는 것이었습니다.


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(*c1) != tolower(*c2)) {
            return false;
        }
    }
    return true;
}

당신이 사용할 수있는 strcasecmp 유닉스에서 또는 stricmp Windows에서.

지금까지 언급되지 않은 한 가지는 이러한 메서드와 함께 stl 문자열을 사용하는 경우 먼저 두 문자열의 길이를 비교하는 것이 유용하다는 것입니다. 이 정보는 이미 문자열 클래스에서 사용할 수 있기 때문입니다.이렇게 하면 비교하는 두 문자열의 길이가 처음부터 같지 않은 경우 비용이 많이 드는 문자열 비교를 수행하는 것을 방지할 수 있습니다.

유니코드를 지원하는 Visual C++ 문자열 함수: http://msdn.microsoft.com/en-us/library/cc194799.aspx

아마도 당신이 찾고 있는 사람은 바로 _wcsnicmp

나는 모든 게시물에서 좋은 답변을 모으려고 노력 중이므로 이것을 편집하는 데 도움을주십시오.

다음은 이를 수행하는 방법입니다. 비록 문자열을 변환하고 유니코드 친화적이지는 않지만 이식성이 있어야 한다는 장점이 있습니다.

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 );
}

내가 읽은 바에 따르면 stricmp()는 실제로 std 라이브러리의 일부가 아니고 대부분의 컴파일러 공급업체에서만 구현되기 때문에 stricmp()보다 이식성이 더 좋습니다.

진정한 유니코드 친화적인 구현을 얻으려면 std 라이브러리 외부로 나가야 하는 것 같습니다.좋은 타사 라이브러리 중 하나는 IBM ICU(유니코드용 국제 구성 요소)

또한 부스트::같음 이런 종류의 비교를 수행하는 데 상당히 좋은 유틸리티를 제공합니다.

그만큼 부스트.문자열 라이브러리에는 대소문자를 구분하지 않는 비교 등을 수행하는 많은 알고리즘이 있습니다.

직접 구현할 수도 있지만 이미 완료되었음에도 불구하고 굳이 귀찮게 할 필요가 있나요?

참고로, strcmp() 그리고 stricmp() null 종결자에 도달할 때까지만 처리하기 때문에 버퍼 오버플로에 취약합니다.사용하는 것이 더 안전합니다 _strncmp() 그리고 _strnicmp().

대소문자를 구분하지 않는 기본적인 문자열 비교 요구 사항에 대해서는 외부 라이브러리를 사용하지 않는 것을 선호하며, 다른 모든 문자열과 호환되지 않는 대소문자를 구분하지 않는 특성을 가진 별도의 문자열 클래스를 원하지도 않습니다.

그래서 제가 생각해낸 것은 다음과 같습니다.

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); });
}

char에 대한 오버로드와 whar_t에 대한 오버로드가 있는 간단한 함수입니다.비표준을 사용하지 않으므로 어떤 플랫폼에서도 괜찮습니다.

동등 비교에서는 가변 길이 인코딩 및 유니코드 정규화와 같은 문제를 고려하지 않지만 basic_string은 내가 알고 있는 이를 지원하지 않으며 일반적으로 문제가 되지 않습니다.

텍스트를 보다 정교하게 사전순으로 조작해야 하는 경우에는 Boost와 같은 타사 라이브러리를 사용하면 됩니다.

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

부스트를 사용할 수 없는 경우 C++14에서 위 코드를 사용할 수 있습니다.당신은 사용해야합니다 std::towlower 넓은 문자의 경우.

짧고 좋네요.이외의 다른 종속성은 없습니다. 펼친 표준 C 라이브러리.

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

보고 진실 만약에 str1 그리고 str2 같다.strcasecmp 존재하지 않을 수도 있고 유사점이 있을 수도 있습니다. stricmp, strcmpi, 등.

예제 코드:

#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;
}

산출:

true
true
true
true
true

보다 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;
}

데모

이미 존재하는 마법 기능이 아닌 방법을 찾고 있다고 가정하면 솔직히 더 좋은 방법은 없습니다.제한된 문자 집합에 대해 영리한 트릭을 사용하여 코드 조각을 작성할 수 있지만 하루가 끝나면 어느 시점에서는 문자를 변환해야 합니다.

이 변환에 대한 가장 좋은 접근 방식은 비교 전에 변환하는 것입니다.이를 통해 실제 비교 연산자는 무시해야 하는 인코딩 체계와 관련하여 상당한 유연성을 얻을 수 있습니다.

물론 이 변환을 자신의 문자열 함수나 클래스 뒤에 '숨길' 수 있지만 여전히 비교하기 전에 문자열을 변환해야 합니다.

내장된 std::basic_string 멤버 함수를 사용하여 비교, 검색 등을 수행할 때 대소문자를 구분하지 않는 std::string을 생성하기 위해 std::basic_string과 함께 사용할 char_traits의 대소문자를 구분하지 않는 버전을 작성했습니다.

그래서 다시 말해서 이런 일을 하고 싶었습니다.

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

assert( a == b );

...std::string이 처리할 수 없는 문제입니다.내 새로운 char_traits의 사용법은 다음과 같습니다.

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

assert( a == b );

...구현은 다음과 같습니다.

/*  ---

        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;

Boost를 사용하지 않고 이 작업을 수행하려면 다음을 사용하여 C 문자열 포인터를 가져옵니다. c_str() 그리고 사용 strcasecmp:

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

나는 좋은 사용 경험을 가지고 있습니다. 유니코드 라이브러리용 국제 구성요소 - 매우 강력하며 변환, 로케일 지원, 날짜 및 시간 렌더링, 대소문자 매핑(원하지 않는 것 같음) 등을 위한 방법을 제공합니다. 대조, 여기에는 대소문자 및 악센트를 구분하지 않는 비교 등이 포함됩니다.저는 C++ 버전의 라이브러리만 사용했는데 Java 버전도 있는 것 같습니다.

@Coincoin이 참조하는 정규화된 비교를 수행하는 방법이 존재하며 로케일도 설명할 수 있습니다. 예를 들어(이는 엄밀히 말하면 동일하지 않은 정렬 예입니다.) 전통적으로 스페인어(스페인)에서 문자 조합 "ll"은 다음과 같습니다. "l"과 "m"이므로 "lz" < "ll" < "ma"입니다.

그냥 사용 strcmp() 대소문자를 구분하고 strcmpi() 또는 stricmp() 대소 문자를 구분하지 않는 비교를 위해.둘 다 헤더 파일에 있습니다 <string.h>

체재:

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

용법:

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;

산출

apple과 AppPlE는 동일합니다.

a가 b 앞에 오므로 apple이 ball보다 앞에 옵니다.

최종적으로 선택한 방법에 대해 메모해 두십시오(해당 방법에 다음의 사용이 포함되는 경우). strcmp 일부 답변은 다음과 같습니다.

strcmp 일반적으로 유니코드 데이터에서는 작동하지 않습니다.일반적으로 utf-8과 같은 바이트 기반 유니코드 인코딩에서는 작동하지 않습니다. strcmp 바이트당 비교만 수행하며 utf-8로 인코딩된 유니코드 코드 포인트는 1바이트 이상이 소요될 수 있습니다.유일한 특정 유니코드 사례 strcmp 올바른 처리는 바이트 기반 인코딩으로 인코딩된 문자열에 U+00FF 이하의 코드 포인트만 포함된 경우입니다. 그러면 바이트당 비교만으로 충분합니다.

2013년 초 현재 IBM이 유지 관리하는 ICU 프로젝트는 이에 대한 꽤 좋은 답변입니다.

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

ICU는 "업계 표준을 밀접하게 추적하는 완전하고 휴대용 유니 코드 라이브러리"입니다. 문자열 비교의 특정 문제의 경우, Collation Object는 원하는 작업을 수행합니다.

Mozilla 프로젝트는 2012년 중반에 Firefox의 국제화를 위해 ICU를 채택했습니다.빌드 시스템 및 데이터 파일 크기 문제를 포함한 엔지니어링 논의를 여기에서 추적할 수 있습니다.

파티에 늦었지만 여기에 다음을 사용하는 변형이 있습니다. std::locale, 따라서 터키어를 올바르게 처리합니다.

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

활성 로케일을 사용하여 문자를 소문자로 변환하는 펑터를 제공합니다. 그런 다음 다음을 통해 사용할 수 있습니다. std::transform 소문자 문자열을 생성하려면 다음을 수행하십시오.

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

이것은 또한 작동합니다 wchar_t 기반 문자열.

위의 솔루션은 비교 메서드를 사용하지 않고 총계를 다시 구현하지 않는 것 같으므로 여기에 내 솔루션이 있으며 이것이 효과가 있기를 바랍니다(잘 작동합니다).

#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;
}

사용하고 싶지 않다면 부스트 라이브러리 그런 다음 C++ 표준 io 헤더만 사용하여 이에 대한 솔루션을 제공합니다.

#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;
}

예를 들어 문자열 벡터가 있는 경우:

std::sort(std::begin(myvector), std::end(myvector), [](std::string const &a, std::string const &b)
{
    return std::lexicographical_compare(std::begin(a), std::end(a), std::begin(b), std::end(b), [](std::string::value_type a, std::string::value_type b)
    {
        return std::tolower(a) < std::tolower(b); //case-insensitive
    });
});

http://ideone.com/N6sq6X

소스 문자열을 다른 문자열과 더 자주 비교해야 하는 경우 한 가지 우아한 해결책은 정규식을 사용하는 것입니다.

std::wstring first = L"Test";
std::wstring second = L"TEST";

std::wregex pattern(first, std::wregex::icase);
bool isEqual = std::regex_match(second, pattern);

C++(Windows에서 테스트됨)에서 두 문자열을 비교하는 간단한 방법은 다음과 같습니다. _stricmp

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

std::string과 함께 사용하려는 경우 예를 들면 다음과 같습니다.

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

자세한 내용은 여기를 참조하세요. https://msdn.microsoft.com/it-it/library/e0z9k731.aspx

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;
        }
      }
}

이것은 아마도 훨씬 더 효율적으로 만들어질 수 있지만 여기에는 모든 부분이 노출된 부피가 큰 버전이 있습니다.

그다지 휴대할 수는 없지만 내 컴퓨터에 있는 모든 파일과 잘 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top