Home PS) JadenCase 문자열 만들기
Post
Cancel

PS) JadenCase 문자열 만들기

출처
: Programmers

문제

JadenCase란 모든 단어의 첫 문자가 대문자이고, 그 외의 알파벳은 소문자인 문자열입니다. 단, 첫 문자가 알파벳이 아닐 때에는 이어지는 알파벳은 소문자로 쓰면 됩니다. (첫 번째 입출력 예 참고)
문자열 s가 주어졌을 때, s를 JadenCase로 바꾼 문자열을 리턴하는 함수, solution을 완성해주세요.

(생략)

나의 풀이

시도했으나 실패한 것

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
'''
정규식 써보기
'''
import re
import collections

def solution(s):
    if (len(s) == 1):
        answer = s.upper()
        return answer
# 1단계: 공백에 대한 전처리
    p = re.compile("[^ ]+")
    space_reg = re.compile("[ ]+")
    # 공백으로 구분됨
    splited_by_space = p.findall(s)
    # 비-공백으로 구분됨
    splited_by_non_space = space_reg.findall(s)

# *** 만약 공백으로만 이뤄진 경우!!
#정규식에는 by_non_space에만 1개의 원소로 잡힘!!!
    if (len(splited_by_non_space) >= 1
        and len(splited_by_space) == 0):
        answer = splited_by_non_space[0]
        return answer
# -------------------------------
# 2단계: 첫 번째가 대문자인지?
    # (이건 iterate 함)

    if (len(splited_by_space) == 1):
        splited_by_space[0] = \
            (splited_by_space[0][0] + splited_by_space[0][1:].lower())

    else:
        for idx_1st, ele_1st in enumerate(splited_by_space):
            for idx_2nd, ele_2nd, in enumerate(ele_1st):
                #  숫자 판별은
                # 인덱스 0일 때만
                if idx_2nd == 0:
                    if ele_2nd.isnumeric() is True:
                        splited_by_space[idx_1st] = \
                            (ele_2nd + ele_1st[1:].lower())
                        break
                    else:
                        # 0번째가 숫자 아니면
                        # 바로 "대"+"소+"로 만들고 break
                        splited_by_space[idx_1st] = \
                            (ele_2nd.upper() + ele_1st[1:].lower())
                        break
                # 1번째부터는 숫자는 안 나옴!!!
                # 대/소문자만 나오는 것만 고려
                # 0번째가 숫자인 경우의 이후에만 여기로 옴
                else:
                    splited_by_space[idx_1st] = \
                        (ele_1st[0] + ele_2nd.upper()
                         + ele_1st[2:].lower())
                    break

    # print(splited_by_space)

# -------------------------------
    # 3단계: 공백 보존!!!!!!!!!!!!! 중요함!!

# -------------------------------
#     print(m)

    if len(splited_by_non_space) == len(splited_by_space):
        # 공백이 먼저 나올 때
        if (s[0].isalnum() is False):
            temp_concat = ''
            for number, ele_space in enumerate(splited_by_non_space):
                temp_concat = ele_space.join([f'{temp_concat}',
                                              f'{splited_by_space[number]}'])
        else:
            temp_concat = ''
            for number, ele_char in enumerate(splited_by_space):
                temp_concat = ele_char.join([f'{temp_concat}',
                                              f'{splited_by_non_space[number]}'])
    elif len(splited_by_non_space) > len(splited_by_space):
        temp_concat = splited_by_non_space[0]
        for number, ele_char in enumerate(splited_by_space):
            temp_concat = ele_char.join([f'{temp_concat}',
                                         f'{splited_by_non_space[number+1]}'])
    elif len(splited_by_non_space) < len(splited_by_space):
        temp_concat = splited_by_space[0]
        for number, ele_space in enumerate(splited_by_non_space):
            temp_concat = ele_space.join([f'{temp_concat}',
                                          f'{splited_by_space[number+1]}'])

    answer = temp_concat
    return answer

처음의 풀이는 정말로 심플했다.
깔끔하게 정규식으로 파싱해내고 끝…..
인 줄 알았으나 절반의 테스트 케이스에서 Fail…

그리고 나서 조건문 덕지덕지 붙인 결과
Fail을 2개로 줄일 수는 있었는데
그 밑으로는 줄이지 못했었다.

그러다 하나씩 다시 체크해보다가
길이가 1인 경우,
정규식 적용 할 것도 없이
바로 처리해서 리턴하는 첫 코드에서
의도와는 다르게 작성된 걸 발견했다!!

1
2
3
    if (len(s) == 1):
        answer = s.upper()
        return answer

원래 의도는 이랬었는데,

1
2
3
    if (len(s) == 1):
        answer = s
        return answer

똑같은 거 대입만 한 사람이 돼버렸다…
이걸 수정하니까 바로 통과…..ㅠㅠㅠㅠ

역시 막힐 때는 다 지우고 다시 시작하는 게
상책인 것 같다. 돌아가도록 하자!



다른 사람들의 풀이

1
2
3
4
5
6
7
8
def solution(s):
    answer = ''
    for i in s.lower().split(' '):
        if answer == '':
            answer += i.capitalize()
        else:
            answer += ' '+i.capitalize()
    return answer

(출처: 프로그래머스 스쿨 다른사람 풀이)

다른 사람 풀이 살펴본 것 중에
이게 가장 심플하면서 좋아보인다.

아예 처음부터 모두 소문자로 만든 뒤에
(알고 있다시피 숫자는 lower()에 안 걸린다.)
대문자 변환 조건을 ''인 변수에 대해서만
적용시키는 것이 아주 좋은 것 같다.

Contents