Creative Commons License

Microsoft .NET

닷넷!시작하기
닷넷! Ver 2.0~
닷넷!스킬업
웹개발
윈폼개발
실용모듈개발
Tip & Tech
하루 한 문법

Microsoft .NET 개발자들을 위한 공간입니다. 기초강의에서 부터 고급 기술 정보 및 팁등을 다루도록 하겠습니다.

.

닷넷!스킬업

닷넷 기술을 조금 더 깊이 다루고자 합니다. 특정 주제를 정하지 않고 이슈 발생 시 마다 체계적으로 정리하여 공유하겠습니다. 이전 자료를 옮겨온 곳이기도 합니다.

문자열 뒤집기

작성자 : 박종명
최초 작성일 : 2009-10-19 (월요일)
최종 수정일 : 2009-10-19 (월요일)
조회 수 : 8771

'문자열 뒤집기'는 정말 단골 메뉴죠...

특히, 신입 개발자을 뽑을 때 자주 등장하는 퀴즈 문제이기도 합니다
이 글에서는, 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 클래스가 정의되어 있습니다
이 자료형을 이용하여 문자열 뒤집기를 간편하게 수행할 수도 있습니다
코드는 생략합니다

∵Commented by 몬난아 at 2009-10-19 오후 5:12:36  
잘봤습니다 ^^
∵Commented by 코드는미궁속으로 at 2013-09-26 오후 9:41:56  
감사합니다. 푸헤
이름
비밀번호
홈페이지
ND <- 왼쪽의 문자를 오른쪽 박스에 똑같이 입력해 주세요