오늘은 실제로 코드를 사용하여 문제를 풀었는데, 각 코드에 대해서 간단히 설명하는 글을 적어보도록 하겠습니다.
문제 1
문제 설명
문자열 s는 한 개 이상의 단어로 구성되어 있습니다. 각 단어는 하나 이상의 공백문자로 구분되어 있습니다. 각 단어의 짝수번째 알파벳은 대문자로, 홀수번째 알파벳은 소문자로 바꾼 문자열을 리턴하는 함수, solution을 완성하세요.
제한 사항
문자열 전체의 짝/홀수 인덱스가 아니라, 단어(공백을 기준)별로 짝/홀수 인덱스를 판단해야합니다.
첫 번째 글자는 0번째 인덱스로 보아 짝수번째 알파벳으로 처리해야 합니다.
def solution(s):
answer = []
idx = 0
for char in s:
if char == ' ':
answer.append(char)
idx = 0
else:
if idx % 2 == 0:
answer.append(char.upper())
else:
answer.append(char.lower())
idx += 1
return ''.join(answer)
- idx = 0: 전체 문자열의 인덱스가 아니라 현재 단어 안에서 몇 번째 글자인지를 기억하는 계수기(Counter)입니다.
- 문자열 s에서 한 글자(char)씩 꺼내어 검사합니다.
- 만약 공백(' ')을 만나면: * 공백은 대소문자 변환이 필요 없으니 그대로 answer에 넣습니다.
- 공백을 만났다는 것은 "기존 단어가 끝나고 새 단어가 시작될 준비를 한다"는 뜻이므로, 단어 내 인덱스인 idx를 다시 0으로 리셋합니다.
- 이 덕분에 공백이 연속으로 여러 개(예: ) 나와도 계속 idx가 0으로 유지되어 안전합니다.
- (else) 공백이 아닌 일반 문자(알파벳)를 만나면:
- 현재 단어 내 인덱스인 idx가 짝수인지 홀수인지 검사합니다.
- 문제 조건에 따라 0번째 인덱스는 짝수로 치기 때문에, 맨 첫 글자(idx=0)는 idx % 2 == 0이 참이 되어 대문자(upper())로 변환됩니다.
- 그 다음 글자는 홀수 인덱스가 되어 소문자(lower())로 변환됩니다.
- 글자 하나를 처리했으니 다음 글자를 위해 idx += 1을 해줍니다.
- 반복문이 모두 끝나면 answer 리스트에는 ['T', 'r', 'y', ' ', 'H', 'e', 'l', 'l', 'o']와 같이 변환된 문자들이 담겨 있습니다.
- 이를 "".join()을 이용해 하나의 예쁜 문자열("Try Hello")로 합쳐서 반환합니다.
문제 2
한국중학교에 다니는 학생들은 각자 정수 번호를 갖고 있습니다. 이 학교 학생 3명의 정수 번호를 더했을 때 0이 되면 3명의 학생은 삼총사라고 합니다. 예를 들어, 5명의 학생이 있고, 각각의 정수 번호가 순서대로 -2, 3, 0, 2, -5일 때, 첫 번째, 세 번째, 네 번째 학생의 정수 번호를 더하면 0이므로 세 학생은 삼총사입니다. 또한, 두 번째, 네 번째, 다섯 번째 학생의 정수 번호를 더해도 0이므로 세 학생도 삼총사입니다. 따라서 이 경우 한국중학교에서는 두 가지 방법으로 삼총사를 만들 수 있습니다.
한국중학교 학생들의 번호를 나타내는 정수 배열 number가 매개변수로 주어질 때, 학생들 중 삼총사를 만들 수 있는 방법의 수를 return 하도록 solution 함수를 완성하세요.
def solution(number):
answer = 0
n = len(number)
for i in range(n):
for j in range(i + 1, n):
for k in range(j + 1, n):
if number[i] + number[j] + number[k] == 0:
answer += 1
return answer
- i (첫 번째 학생): 가장 앞에 서는 학생입니다. 뒤에 최소한 2명(j, k)은 더 있어야 하므로 실제로는 배열의 끝에서 세 번째 자리까지만 의미가 있습니다.
- j = i + 1 (두 번째 학생): 무조건 첫 번째 학생(i)의 오른쪽부터 선택을 시작합니다. 이 덕분에 i와 j가 같은 학생을 가리키는 중복이 발생하지 않습니다.
- k = j + 1 (세 번째 학생): 무조건 두 번째 학생(j)의 오른쪽부터 선택을 시작합니다. 같은 원리로 j나 i와 겹치지 않습니다.
문제3
숫자로 이루어진 문자열 t와 p가 주어질 때, t에서 p와 길이가 같은 부분문자열 중에서, 이 부분문자열이 나타내는 수가 p가 나타내는 수보다 작거나 같은 것이 나오는 횟수를 return하는 함수 solution을 완성하세요.
예를 들어, t="3141592"이고 p="271" 인 경우, t의 길이가 3인 부분 문자열은 314, 141, 415, 159, 592입니다. 이 문자열이 나타내는 수 중 271보다 작거나 같은 수는 141, 159 2개 입니다.
def solution(t, p):
answer = 0
p_len = len(p)
p_num = int(p)
for i in range(len(t) - p_len + 1):
sub_num = int(t[i : i + p_len])
if sub_num <= p_num:
answer += 1
return answer
- p_len: 매번 len(p)를 계산하면 비효율적이므로 변수에 미리 저장해 둡니다. 이 길이는 문자열을 자르는 기준이 됩니다.
- p_num: 문자열끼리 대소 비교를 하면 사전순으로 비교가 되어 엉뚱한 결과가 나올 수 있으므로, 확실하게 크기를 비교하기 위해 정수(int)로 미리 바꾸어 놓습니다.
왜 len(t) - p_len + 1 인가요?
-
- t의 길이가 7이고 p가 3일 때, 마지막으로 잘라낼 수 있는 글자는 맨 끝의 592(인덱스 4, 5, 6)입니다.
- 즉, 시작 인덱스 i는 4까지만 가야 합니다.
- 7 - 3 + 1 = 5가 되어 range(5)는 0, 1, 2, 3, 4까지 돌게 되므로 딱 마지막 글자까지만 안전하게 검사할 수 있게 해줍니다. (범위를 벗어나는 에러 방지)
- t[i : i + p_len]: 파이썬의 가장 강력한 기능 중 하나인 슬라이싱입니다. i부터 i + 3 직전까지의 문자열을 쏙 빼옵니다.
- 꺼내온 문자열(예: "314")을 곧바로 int()를 감싸 숫자로 변환합니다
- 방금 잘라 만든 숫자(sub_num)가 기준인 p_num(271)보다 작거나 같은지 비교합니다.
- 조건이 참일 때만 결과 카운트(answer)를 1씩 올려줍니다.