이 글에서는 두 문자열을 비교하되 문자의 대소문자는 무시하는 strcmp(문자열 비교) 함수를 직접 만들어 보겠습니다. 이 함수는 string1 < string2일 때 -1, string1 = string2일 때 0, string1 > string2일 때 1을 반환해야 합니다.
먼저 예시를 통해 문제를 살펴보겠습니다.
입력
string1 = "Hello", string2 = "hello"
출력
0
"Hello"와 "hello"는 대소문자만 다를 뿐 같은 단어이므로, 두 문자열은 동일하다고 판단되어 0이 반환됩니다.
접근 방법
대소문자를 무시하며 문자열을 비교하는 자체 strcmp 함수를 만들려면, 두 문자열의 문자를 앞에서부터 한 글자씩 순회하며 비교합니다. i번째 인덱스의 문자가 서로 같다면(string1[i] == string2[i]) 다음 문자로 넘어가고, string1[i] > string2[i]이면 1을, string1[i] < string2[i]이면 -1을 반환합니다. 한쪽 문자열이라도 끝에 도달할 때까지 차이가 없었다면 0을 반환합니다.
대소문자를 무시하는 원리
여기서 핵심은 'A'와 'a'를 같은 문자로 취급하는 것입니다. 이때 문자의 ASCII 값을 활용하면 간단하게 처리할 수 있습니다. 영어 알파벳에서 대문자와 소문자의 ASCII 값은 정확히 32만큼 차이가 납니다. 예를 들어 'a'의 ASCII 값은 97이고, 'A'의 ASCII 값은 65입니다.
XOR(^) 연산으로 32를 적용하면 해당 알파벳의 대소문자가 서로 전환되고, OR(|) 연산으로 32를 적용하면 모든 알파벳이 소문자 기준 값으로 통일됩니다. 이러한 비트 연산의 성질을 이용하면 별도의 변환 함수 없이도 대소문자를 무시한 비교를 손쉽게 구현할 수 있습니다.
구현 예제
#include <iostream>
using namespace std;
int strcmpFunc(string string1, string string2){
int i;
for (i = 0; string1[i] && string2[i]; ++i){
if (string1[i] == string2[i] || (string1[i] ^ 32) == string2[i])
continue;
else
break;
}
if (string1[i] == string2[i])
return 0;
if ((string1[i] | 32) < (string2[i] | 32))
return -1;
return 1;
}
int main(){
cout<<"Comparing strings using our strcmp function :\n";
cout<<"Result: "<<strcmpFunc("HELLO", "hello")<<endl;
cout<<"Result: "<<strcmpFunc("", "Hello")<<endl;
cout<<"Result: "<<strcmpFunc("Tutorials", "Pint")<<endl;
cout<<"Result: "<<strcmpFunc("afdadsa", "rewf")<<endl;
cout<<"Result: "<<strcmpFunc("tutorialspoint", "TUTORIALSpoint")<<endl;
return 0;
}
실행 결과
Comparing strings using our strcmp function − Result: 0 Result: -1 Result: 1 Result: -1 Result: 0
코드 상세 설명
strcmpFunc 함수는 두 문자열을 인덱스별로 순회하며 비교합니다. 루프 조건 string1[i] && string2[i]는 두 문자열 중 어느 하나라도 끝에 도달하면 반복을 멈춥니다. 루프 안에서는 두 문자가 완전히 같은 경우와, XOR 32 연산 결과가 같아지는 경우(즉, 대소문자만 다른 경우)를 continue로 건너뜁니다.
루프가 끝난 후에는 세 가지 경우로 나누어 결과를 반환합니다. 현재 위치의 문자가 같다면 두 문자열이 완전히 동일하다는 의미로 0을 반환하고, (string1[i] | 32)가 (string2[i] | 32)보다 작다면 string1이 사전순으로 앞선다는 의미로 -1을 반환합니다. 그 외의 경우에는 1을 반환합니다. OR 연산으로 32를 적용하면 알파벳이 모두 소문자 기준으로 변환되므로, 대소문자와 관계없이 올바른 크기 비교가 가능합니다.