'문자열 뒤집기'는 정말 단골 메뉴죠...
특히, 신입 개발자을 뽑을 때 자주 등장하는 퀴즈 문제이기도 합니다
이 글에서는, C#으로 문자열 뒤집는 여러 방법에 대해 알아 보겠습니다
문자열을 뒤집는 메서드 이름을 Reverse로 하고 매개변수는 대상 문자열 입니다
Reverse의 반환 값은 뒤집혀진 문자열 입니다
명세: string Reserve(string)
1. 문자열을 뒤에서 -> 앞으로 돌면서 새 문자열을 만드는 방법
대부분, 가장 먼저 떠오르는 모습이 아닐까 합니다. 문자열을 거꾸로 돌면서 뒤집혀진 문자열을 만드는 방법입니다
static string Reverse(string s)
{
StringBuilder resultStr = new StringBuilder();
for (int i = s.Length - 1; i >= 0; i--)
{
resultStr.Append(s[i]);
}
return resultStr.ToString();
}
for 문의 열거 방법이, 뒤에서 앞으로 입니다. 뒤에서 앞으로 돌면서 글자 하나하나 더해가는 방식이죠
이 코드에서는 반복문이 문자열 수 만큼 돌게 됩니다
참고로, 여기서는 StringBuilder 을 사용했습니다.
string 은 유명한(?) immutable 객체이죠. 즉 불변의, 변하지 않는 객체라는 뜻으로,
string s += "문자열" 연산할 때, 계속 새로운 객체가 생성되어 버립니다. 이전 객체는 가비지(Garbage)객체가 되구요
따라서 string 대신 StringBuilder을 사용했습니다
string 과 StringBuiler 의 비교는 이 글의 주제에 벗어나므로, 다른 자료를 찾아 보세요. (단 중요합니다)
2. 중앙으로 부터 좌우 대칭되는 값을 치환하는 방법
앞서 1번 코드는, 반복 횟수가 문자열 수 만큼 된 것에 비해 여기서는 그 절반(1/2)으로 줄입니다
'abcd' 라는 문자열을 뒤집으면 'dcba' 가 됩니다
이는 문자열 중간을 기점으로 양쪽 대칭되는 값을 치환해 주면 되는 것이죠
아래 그림을 보세요. 금방 이해가 갈 겁니다
마치 '이진 탐색'의 발상과 살짝 유사하기도 하죠 (참고) => 이진탐색 구현하기
노파심에, 글자 수가 홀수개 이면 어떨까요. 다시 말해 'abcde' 를 뒤집는다면?
중간값은 신경 쓸 필요가 없죠. 중간값은 뒤집어도 중간에 그대로 있으면 되니깐요..
static string Reverse(string s)
{
char[] chars = s.ToCharArray();
int length = chars.Length;
for (int i = 0; i < length / 2; i++)
{
int pos = length - i - 1;
char c = chars[i];
chars[i] = chars[pos];
chars[pos] = c;
}
return new string(chars);
}
반복 횟수가 절반으로 줄었습니다. 문자열이 굉장히(?) 기~~일 경우 그 연산 속도가 산술적으로는 1/2가 되겠죠
다만, 산술적으로 입니다. 중요한 것은 환경이겠죠 ㅋㅋ
3. 닷넷 프레임워크의 도움을 받읍시다
친절한 닷넷이 이러한 api 를 지원하지 않을리가 없지 않겠습니까?? ㅎㅎ
System.Array 객체에 Reverse 라는 정적 메서드가 있습니다
배열을 뒤집어 주는 메서드로써, 우리가 구현하려고 하는 문자열 뒤집기에 이용할 수 있습니다
문자열도 char 의 집합, 즉 char 배열이죠. 따라서 Array.Reverse(char[])로 가능합니다
static string Reverse(string s)
{
char[] chars = s.ToCharArray();
Array.Reverse(chars);
return new string(chars);
}
그리고 닷넷 프레임워크 3.5 이상 사용한다면, IEnumerable 타입의 Reverse도 이용 가능합니다
static string Reserve(string s)
{
return new string(s.ToCharArray().Reverse().ToArray());
}
4. 닷넷 프레임워크가 구현한 내부 코드를 따라 합시다
Array.Reverse 내부 구현 코드를 reflector 로 까보게 되면 아래와 같습니다

for 문 대신 while문을 사용했는데요,
앞서 2번 방법인 1/2 Loop 와 결과적으로 동일합니다
for문 대신 while 문을 사용하지만, 이 코드 역시 끝에서 부터 중앙으로 오면서 값을 치환해 가는
방법으로, 반복의 횟수를 문자열수/2 로 줄일 수 있습니다. 아래 코드는 이같은 방식으로 구현된 코드 입니다
static string Reverse(string s)
{
char[] chars = s.ToCharArray();
int startIndex = 0;
int lastIndex = chars.Length - 1;
while (startIndex < lastIndex)
{
char c = chars[startIndex];
chars[startIndex] = chars[lastIndex];
chars[lastIndex] = c;
startIndex++;
lastIndex--;
}
return new string(chars);
}
5. 스택(Stack) 자료구조 이용하기
스택은 후입선출(LIFO, Last In First Out) 즉 가장 마지막에 입력된 자료가 가장 먼저 출력되는 특징을 가진
아주 유명한(?) 자료구조 입니다
문자열을 뒤집는다는 것 자체가 abcd -> dcba , 즉 뒤에서 부터 차례로 배치시키는 구조이기 때문에
스택의 특성을 이용할 수 있습니다
닷넷 프레임워크에는 Stack 클래스가 정의되어 있습니다
이 자료형을 이용하여 문자열 뒤집기를 간편하게 수행할 수도 있습니다
코드는 생략합니다