[Python-CodingTest] 5-9. 아나그램 (딕셔너리 해쉬 & 리스트 해쉬)
아나그램
문제 정리
입력
AbaAeCe
baeeACA
처리 과정
- 한 개의 딕셔너리 생성 (
key
: 알파벳,value
: 개수) - 입력받은 첫번째 스트링(
str1
)을 돌며 딕셔너리에+1
- 입력받은 두번째 스트링(
str2
)을 돌며 딕셔너리에서-1
- 딕셔너리에서
str1
(혹은str2
)의 요소를key
값으로 하는value
들 중에0
이 아닌게 있다면 NO - 모두
0
이라면 YES
출력
YES
내 답
import sys
sys.stdin = open("./input/in9.txt", "rt")
lst1=list(input())
lst2=list(input())
dic1=dict()
dic2=dict()
for x in lst1:
# 카운트 하기 (1씩 누적)
dic1[x]=dic1.get(x,0)+1 # dic1.get(x,0): dic1의 key 중에 x가 있으면 그 value를 리턴하고 없으면 0을 리턴
for x in lst2:
dic2[x]=dic2.get(x,0)+1
for key1,val1 in dic1.items():
if any(key1==key2 and val1==val2 for key2,val2 in dic2.items()):
continue
else:
print('NO')
break
else:
print('YES')
풀이 - 1: 두 개의 딕셔너리 사용
import sys
sys.stdin = open("./input/in9.txt", "r")
# 두 단어는 스트링으로 입력 받음
str1=input()
str2=input()
dic1=dict()
dic2=dict()
for x in str1:
# 카운트 하기 (1씩 누적)
dic1[x]=dic1.get(x,0)+1 # 🌟 dic1.get(x,0): dic1의 key 중에 x가 있으면 그 value를 리턴하고 없으면 0을 리턴
for x in str2:
dic2[x]=dic2.get(x,0)+1
for i in dic1.keys(): # dic1의 key값들만 i로 접근
if i in dic2.keys(): # dic1의 key값이 dic2에 존재한다면
if dic1[i]!=dic2[i]: # value를 비교
print('NO')
break
else: # dic1의 key값이 dic2에 존재하지 않는다면
print('NO')
break
else: # break로 종료되지 않는다면 실행
print('YES')
딕셔너리를 두 개가 아닌 하나만 사용하도록 아래처럼 개선할 수 있다.
풀이 - 2: 한 개의 딕셔너리 사용
import sys
sys.stdin = open("./input/in9.txt", "r")
# 두 단어는 스트링으로 입력 받음
str1=input()
str2=input()
dic=dict()
for x in str1:
dic[x]=dic.get(x,0)+1 # 카운트 하기 (+1)
for x in str2:
dic[x]=dic.get(x,0)-1 # 카운트 했던 것을 다시 복귀 (-1)
for x in str1:
if dic.get(x)!=0: # 🌟 dic에서 key가 x인 요소의 value를 리턴
print('NO')
break
else:
print('YES')
# 혹은 아래처럼도 가능!
# for val in dic.values():
# if val!=0:
# print('NO')
# break
# else:
# print('YES')
풀이 - 3: 리스트 해쉬
import sys
sys.stdin = open("./input/in9.txt", "r")
str1=input()
str2=input()
# 알파벳 대문자(26개) & 소문자(26개)
# str1은 lst1에 해싱, str2는 lst2에 해싱할 것!
lst1=[0]*52
lst2=[0]*52
# A(=65) ~ Z(=90)
# a(=97) ~ z(=122)
# str의 요소를 돌며 lst에 알파벳의 개수를 카운트하는 함수
def hashingStr(lst,str):
for x in str:
if x.isupper(): # x가 대문자라면
lst[ord(x)-65]+=1 # ord(): 문자를 아스키넘버로 변환 # 🌟 인덱스 번호가 0부터 시작하도록 (65-65=0)
else: # 소문자라면
lst[ord(x)-71]+=1 # 🌟 lst1의 0~25번 인덱스는 대문자로 차있기 때문에, 소문자는 26번부터 시작하도록 (97-71=26)
hashingStr(lst1,str1) # 첫번째 단어 해싱
hashingStr(lst2,str2) # 두번째 단어 해싱
# c++스러운 방법
for i in range(52):
if lst1[i]!=lst2[i]:
print('NO')
break
else:
print('YES')
# 파이썬스러운 쉬운 방법
# if lst1==lst2: # 🌟 두 리스트의 값이 정확하게 모두 같은지 확인
# print('YES')
# else:
# print('NO')
정리
dic.get(x)
: dic에서 key가 x인 요소의 value를 리턴dic.get(x,0)
: dic의 key 중에 x가 있으면 그 value를 리턴하고 없으면 0을 리턴dic[x]=dic.get(x,0)+1
처럼 누적하면서 카운트 할 때 유용- for문을 이용해 딕셔너리의 요소에 접근하는 방법
for key,val in dic.items()
: key와 value 쌍에 접근
for key in dic.keys()
: key에 접근
for val in dic.values()
: value에 접근 ord()
: 문자를 아스키넘버로 변환if lst1==lst2
: 두 리스트의 값이 정확하게 모두 같은지 확인
💛 개인 공부 기록용 블로그입니다. 👻