[알고리즘] 이상한 문자 만들기

DongGyu Jung·2021년 10월 23일
0
post-thumbnail

※ 본 사진과 해당 게시글 내용의 문제 모두 프로그래머스[Programmers]사이트에 발췌해왔습니다.


❓ 문제

문자열 s는 한 개 이상의 단어로 구성되어 있습니다.
각 단어는 하나 이상의 공백문자로 구분되어 있습니다.
각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴하는 함수,
solution을 완성하세요.

제한 조건 : 
문자열 전체의 짝/홀수 인덱스가 아니라, 단어(공백을 기준)별로 짝/홀수 인덱스를 판단해야합니다.
첫 번째 글자는 0번째 인덱스로 보아 짝수번째 알파벳으로 처리해야 합니다.

<입출력 >
        s	         |  return
"try hello world"	 |  "TrY HeLlO WoRlD"

<입출력  설명>
"try hello world"는 세 단어 "try", "hello", "world"로 구성되어 있습니다.
각 단어의 짝수번째 문자를 대문자로, 홀수번째 문자를 소문자로 바꾸면
"TrY", "HeLlO", "WoRlD"입니다. 따라서 "TrY HeLlO WoRlD" 를 리턴합니다.

❗ 풀이

My Code

def solution(s):
    words = s.split(' ')
    new = []
    for w in words :
        s=[]
        for i in range(len(w)):
            if i%2 == 0 :
                s.append(w[i].upper())
            else :
                s.append(w[i].lower())
        new.append(''.join(s))
    return " ".join(new)

우선 공백을 기준으로 단어를 나눠지는 조건이기 때문에
.split(' ')으로 입력된 문자열을 각 단어 단위로 나눠진 리스트를 생성한다.

첫번째 for문을 시작하기 전에 새롭게 이상하게(?) 바꾼 단어를 담아주기 위해
new 라는 빈 리스트를 생성한다

For문 1️⃣

  • 공백으로 나눠진 단어들 각각 가져오기 위해 for w in words:
  • 대문자 혹은 소문자로 변환된 철자를 담아주기 위해 s라는 빈 리스트를 만들어준다.
  • 두 번째 For문에서 만들어진 철자들을 공백없이 붙여주어 한 단어로 만든다.(''.join(s))

For문 2️⃣

  • 대소문자 변환 기준이 철자들의 자릿수 홀짝여부이기 때문에 인덱싱을 하기 위해서 단어의 길이가 필요하다.
    따라서 for i in range(len(w)) :로 각 자릿수를 인덱싱할 숫자 범주를 만들어준 후
    i%2 조건의 IF~Else문으로 각 짝수/홀수 자릿수 값들을 변환하여
    앞서 만든 변환된 철자를 담는 s 리스트에 삽입해준다.(s.append(w[i].~))

마지막으로
변환되어 만들어진 단어들을 공백으로 부여하여 합쳐준 문자열을 반환하면 된다. (return " ".join(new))

❣ 다른 풀이

(1)

def toWeirdCase(s):
    return " ".join(map(lambda x: "".join([a.lower() if i % 2 else a.upper() for i, a in enumerate(x)]), s.split(" ")))

어찌.. 다른 사람들의 풀이는 다 한 줄인거지...
(알고리즘 문제 풀기의 또 다른 비전은 "모든 알고리즘을 한 줄로!!" 인 것인가...)

map()함수를 통해 필자가 구현했던 for문으로 함수 적용하는 것을 축약시켰다.
인수로 투입된 함수는 lambda..!!
이 람다 함수의 x는 입력값을 공백을 기준으로 split한 값이다. (두 번째 인수인 s.split(" "))

적용시키는 함수는 리스트 컴프리헨션으로
for문이 적용되는 대상으로 enumerate(x)로 각 값에 인덱스(index) 값을 zip한 값들의 행렬을 주었고
i(인덱스), a(철자)를 가져와 필자의 풀이처럼 i % 2 조건의 if~else문을 주었다.
output은
변환된 철자 리스트이기 때문에
마지막에 "".join으로 람다함수를 끝마친다.

그렇게 결과적으로 변환된 철자들로 구성된 단어들이 만들어지고
최종적으로
" ".join()한 값을 return해준다.

(2)

def toWeirdCase(s):
    return ' '.join([''.join([c.upper() if i % 2 == 0 else c.lower() for i, c in enumerate(w)]) for w in s.split()])

얼핏 보면 위 (1)풀이와 비슷해보일 수 있지만
map()함수나 lambda함수를 사용하지 않고
for문을 2번 적용시킨 방법이다.

해당 풀이에서도 필자의 range(len(w))의 방법이 아닌
자동으로 인덱스를 부여하는 enumerate()함수를 사용하였다.

0개의 댓글