군더더기 없는 기계학습 백과사전

[30일 챌린지] 문자열 옮기기 (Perform String Shifts) 본문

Data Structures and Algorithms/Leetcode

[30일 챌린지] 문자열 옮기기 (Perform String Shifts)

Jay김 2020. 4. 15. 07:59

목표

당신에게 소문자 영단어가 들어가 있는 문자열(string) 's'와 행렬(matrix) 'shift'가 주어질 것이다. 다르게 보면 리스트로 이루어진 리스트인 'shift'의 내용물은 다음과 같다.

shift [i] = [방향, 칸 수]

방향 값은 0 혹은 1이다. 0은 왼쪽 1은 오른쪽이다.

칸 수 값은 해당 방향으로 몇 칸 옮겨야 (shift) 하는지 가리킨다.

주어진 입력값에 따라 출력값을 내는 함수를 정의하라.

예시 1

입력값: s = "abc", shift = [[0,1], [1,2], [0,3]]

출력값: "cab"

해설: [0,1] 은 왼쪽으로 1칸 이동을 명령한다. "abc" → "bca"

[1,2] 은 오른쪽으로 2칸 이동을 명령한다. "bca" → "cab"

[0,3] 은 왼쪽으로 3칸 이동을 명령한다. "cab" → "cab"

답 1

바로 파이썬의 인덱스 슬라이싱이 생각날 것이다. 문자열 자체의 내용물을 바꾸는 것이 아니라 문자열을 변경시킨 카피를 만들고 문자열의 주소를 가리키는 변수 s를 변경시키는 것이기 때문에 변경 불가 개체 에러가 날 염려는 없다. 

알고리즘은 다음과 같다.

    1. shift 행렬을 for 루프로 읽는다.
    2. shift 행렬에 들어있는 리스트의 인덱스 0을 확인해 방향 값을 읽는다. 이때 if 문으로 0 혹은 1에 따라 실행할 작업을 나눠준다.
    3. 문자를 이동한 수에서부터 인덱스 슬라이싱을 하여 서브 문자열을 만들고 거기에 나머지 문자열 내용이 들어있는 서브 문자열을 더해준다. 예를 들어 "abc"에 [0,1] 작업을 실행한다면 "bca"가 된다. 이는 곧 리스트를 인덱스 1부터 인덱스 2까지 읽은 뒤 다시 인덱스 0부터 시작하는 것과 동일한 작업이 된다. 그러니까 s [1:]+s [:1] = "bc" + "a" = "bca"로 같은 결과물에 도달할 수 있다. 오른쪽으로 이동하는 [1,1] 작업을 실행한다면 s [-1:] + s [:-1]를 실행하면 된다. 인덱스 -1 은 곧 끝의 인덱스와 동일하다. 즉, "c" + "ab" = "cab"라는 결과물에 도달할 수 있다.
    4. 이 결과물을 다시 s에 다시 지정(assign)해준다.
1
2
3
4
5
6
7
8
def stringShift(s, shift):
    for i in shift:
        if i[0== 0:
              s = s[i[1]:]+s[:i[1]]
        else:
              s = s[-i[1]:]+s[:-i[1]]
                
        return s
cs

답 2

즉시 shift에서 값을 선언하고 사용하는 방법이다. 살짝 더 빠르다.

1
2
3
4
5
6
7
8
def stringShift(s, shift):
    for 방향, 칸수 in shift:
        if 방향 == 0:
              s = s[칸수:]+s[:칸수]
        else:
              s = s[-칸수:]+s[:-칸수]
                
        return s
cs

 

추가 답 

살짝 더 빠르게 만들고자 한다면 같은 왼쪽 칸 수 이동과 오른쪽 칸 수 이동이 곧 제자리라는 사실을 이용하자.

[Copyright ⓒ 블로그채널 무단전재 및 재배포 금지]

'Data Structures and Algorithms > Leetcode' 카테고리의 다른 글

844. Backspace String Compare  (0) 2020.04.13
Comments