백준 1316번 (그룹 단어 체커完)
디버깅용
import sys
n = int(sys.stdin.readline().strip())
chek=0
group_word=[]
for i in range(n):
judge =[0]
word = sys.stdin.readline().strip()
values=['']
print(f'word: {word}, len: {len(word)}')
for k,v in enumerate(word):
values.append(v)
if word.count(v) ==1:
judge.append(0)
print(f'solo! \nk:{k}, v: {v}, \nafter judge: {judge}')
print('!'*10)
else :
judge.append(k)
print('k:', k, 'v:', v)
print('values:',values , 'pre value:', values[k])
print('bfore judge:', judge)
print('before k-1:', k-1)
if v == values[k]:
print('cal')
judge[k+1]= abs( k - (k-1))
if v != values[k] and values[k+1] in values[:-2]:
print('not groupword!')
judge[0]=-1
print('after judge:', judge)
print('-'*10)
if judge[k+1] == 1:
judge[k]=0
judge[k+1]=0
print('reset')
print('judge:', judge)
print('-'*10)
if len(word)+1 == judge.count(0):
print('*'*10)
print('len word', len(word))
print(judge)
print('*'*10)
chek+=1
group_word.append(word)
print(group_word)
print(chek)
나는 안되면 뭔가를 엄청 덧붙여서 문제를 풀고 싶어하는 경향이 있는 것 같다.
이번에도 안되니깐 알파벳마다 따로 딕셔너리를 이용해야 겠다는 생각이 들었다.
그런데 신기하게 복잡하게 생각하면 갑자기 앗! 하고 깨달음을 얻는다.
핵심은
if v != values[k] and values[k+1] in values[:-2]:
print('not groupword!')
judge[0]=-1
연속된 그룹이 한번 끊긴 후 다시 재개하는 바람에 문제가 생겼다.
이 문제를 해결하기 위해 단어가 바뀌었을 때 이미 앞에 있었다면 맨 앞에 -1을 넣었다.
if len(word)+1 == judge.count(0):
에서 걸러진다.
len(word)
judge는 맨 처음에 0을 넣고 시작하니 +1을 해야한다.
나의 풀이(최종)
import sys
n = int(sys.stdin.readline().strip())
chek=0
for i in range(n):
judge =[0]
word = sys.stdin.readline().strip()
values=['']
for k,v in enumerate(word):
values.append(v)
if word.count(v) ==1:
judge.append(0)
else :
judge.append(k)
if v == values[k]:
judge[k+1]= abs( k - (k-1))
if v != values[k] and values[k+1] in values[:-2]:
judge[0]=-1
if judge[k+1] == 1:
judge[k]=0
judge[k+1]=0
if len(word)+1 == judge.count(0):
chek+=1
print(chek)
다른 사람의 풀이(1)
N = int(input())
count = 0
for _ in range(N):
string = input()
if list(string) == sorted(string, key=string.find):
count += 1
print(count)
어라...?
왜 이렇게 쉽지????
key=string.find
이 핵심이다.
이 함수를 이용하여 기준을 정하면 리스트의 요소에서 앞에 나오는 순대로 번호를 부여하여 정렬한다.
예시
s = "google"
sorted_s = sorted(s, key=s.find)
print("".join(sorted_s))
- 'g' (find("g") = 0)
- 'g' (find("g") = 0)
- 'o' (find("o") = 1)
- 'o' (find("o") = 1)
- 'l' (find("l") = 3)
- 'e' (find("e") = 4)
결과: "ggoole"
그룹 단어 개념
- 하나의 알파벳이 여러개면 붙어있다.
- 하나의 알파벳 묶음은 다른 알파벳의 묶음 혹은 다른 단일문자 뒤에 다시 사용될 수 없다.
위의 개념을 확실히 이해하고 find
를 이용하여 같은 알파벳끼리 붙어 있게 만들었다.
이러면 원래 입력값이랑 비교해서 같으면 그룹이다.
sorted(iterable, key=None, reverse=False)
iterable | 정렬할 대상 (리스트, 튜플, 문자열, 딕셔너리 등) |
---|---|
key | 정렬 기준을 정의하는 함수 (기본값 None) |
reverse | True일 경우 내림차순, False일 경우 오름차순 (기본값 False) |
key=lambda x: x.find("a") 이런식으로 특정 알파벳이 먼저 나오는걸 찾게 할 수도 있다
진짜... 아는게 힘이다...
다른 사람의 풀이(2)
N = int(input())
cnt = N
for _ in range(N):
word = input()
for i in range(len(word)-1):
if word[i] == word[i+1]:
pass
elif word[i] in word[i+1:]:
cnt -= 1
break
print(cnt)
이 분은 문자열에서 전의 단어와 현재의 단어가 같으면 pass
같은 알파벳 묶음이라는 것이니 딱히 뭘 할 필요가 없다.
해당 문자가 문자열 안에 있으면 조작을 한다.
단어가 바뀌었을 때 해당 단어가 문자열 안에 있다면 이미 쓰인 묶음 혹은 단어가 사용됐다는 의미
후기
나에겐 너무 어려웠는데 정답률이 50%가 넘길래 의아했었다.
그런데 다른 사람들이 푼 것을 보니 파이썬을 잘 알거나 혹은 문제의 본질을 잘 캐치한 사람에겐 쉬웠던 문제였다.
파이썬을 잘 아는 것은 많은 문제를 풀며 함수를 접하면 해결될 부분이라 생각한다.
문제는 후자다.
나같은 경우는 일단 뭐라도 풀고 억지로 길을 뚫어낸다.
(왠지 내가 처음 생각한대로 못풀면 포기한 느낌이 들어 찝집하다)
하나를 진득하게 하는걸 나쁘게 생각하진 않지만 역시 무빙하고 생각하는건 티어를 높이기엔 매우 불리한것 같다.
이제부터 핵심을 생각하고 무빙하는걸 의식적으로 계속 해야겠다.