N = int(input()) #글자수
for i in range(N):
s = input()
s = s.upeer() # 문자열의 대문자화
size = len(s) #문자열의 길이
for j in range (size//2):
if s[j] != s[-j-1]:
print("#%d NO" %(i+1)) #i는 몇 번째 케이스인지.
break
else: #위에서, break 안 당하고 정상적으로 종료됐다는 뜻
print("#%d YES %(i+1)")
1. 문제
2. 내가 생각한 알고리즘
- 홀수와 짝수를 나누어서 생각해본다. (홀수는 기준점을 고려 안해도 되지만, 짝수는 기준점도 고려된다)
- 기준점 (글자수 / 2 )을 기준으로 왼쪽 리스트 vs 오른쪽 리스트로 나눠서 글자를 저장한다.
=> 이 때, 문자열 슬라이싱 개념 이용
- 왼쪽 리스트의 경우, 앞에서 뒤로 읽고, 오른쪽 리스트의 경우 뒤에서 앞으로 읽어서, 각각의 원소들이 i라는 인덱스에서 모두 동일해야지, 회문을 만족.
-오른쪽 리스트의 경우, 뒤에서 앞으로 읽는 문제를 해결하기 위해,[::-1]을 사용
- [::-1]은 시퀀스 객체를 역순으로 반환하는 것을 의미
ex) my_list = [1,2,3,4,5]
my_list[::-1] // [5,4,3,2,1]
[::-1] 파이썬에서 리스트, 문자열, 튜플 등 시퀀스(sequence) 객체를 역순으로 반환하기 위해 사용되는 슬라이싱(slicing) 구문입니다.
슬라이싱 시작:끝:간격의 형태로 사용되며, 생략된 값은 기본값으로 처리됩니다. [::-1]에서 시작과 끝은 비어있으며, 간격이 -1로 설정되어 있습니다.
아놔....문제 이해 완전 잘못했다. N은 입력하는 단어의 갯수였다.
3. 문제 풀이
홀수일 때, 짝수일 때 다른 부분 : 오른쪽 리스트의 시작점
4. 강의 코드 + 설명
방식1
N = int(input()) #글자수
result = list(input()) #입력한 단어를 개별 문자로 리스트화 해서, result에 저장
# [a,p,p,l,e] 이렇게 저장 될거임
if(N % 2 !=0): #문자 수가 홀수이면
left = list(result[:N//2])
right = list(result[(N//2)+1:][::-1])
else:
left = list(result[:N//2])
right = list(result[N//2:][::-1])
for i in range (len(left)):
if(left[i] != right[i]):
print("No")
break
print("Yes")
'대소문자 구분 없이' 라는 조건을 만족하려면, gooG도, 회문문자로 인정한다는 뜻이다.
-> 애초에 소문자 + 대문자가 섞인 단어의 경우, 모두 대문자로 고쳐놓고 비교 들어가면, 조건을 고려하는 알고리즘이 될 것이다.
인덱스를 탐색할 때 '뒤에서부터 접근할 수 있다. 이 때, -1부터 시작한다! (기억)
방식 2
N = int(input()) #글자수
for i in range(N):
s = input()
s = s.upeer() # 문자열의 대문자화
if s==s[::-1]:
print("#%d YES %(i+1)")
else:
print("#%d NO %(i+1)")
맨 뒷자리부터, -1씩 작아지면서 문자열을 거꾸로 해라!
5. 반성한 점
문제를 제대로 안읽어서, 이상한 알고리즘을 생각하고 있었다.
조건도 제대로 안 읽었다. '대소문자 구분 없이' 라는 조건이 있었는데, 그걸 생각 못했다.
6. 새로 알게된 점
s[::-1]
reverse 인덱스 슬라이싱
7. 아맞다
1. 문자열.upper()
: 문자열을 모두 대문자로 바꾼다.
2. index접근을 거꾸로도 할 수 있다! 0-1-2-3-4 vs -1,-2,-3,-4,-5
3. if문 + break & else문
if문에서 break를 안 당하고, 정상적으로 빠져나왔을 때, else의 위치(들여쓰기) 기억. if랑 나란한게 아니다.