Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

파이썬으로 두 숫자의 이진 표현이 아나그램인지 확인하는 프로그램

두 개의 숫자가 주어졌을 때, 두 숫자의 이진수(binary) 표현이 서로 아나그램(anagram) 관계인지 확인하는 것이 이번 포스팅의 목표입니다. 여기서 아나그램이란, 구성 요소는 같지만 순서만 다른 경우를 의미합니다. 즉, 두 숫자의 이진 표현에 포함된 0과 1의 개수가 각각 동일하다면 두 숫자는 이진 아나그램이라고 할 수 있습니다.

파이썬에서는 collections 모듈의 Counter(iterable) 메서드와 딕셔너리 비교를 활용하면 이 문제를 매우 간단하고 빠르게 해결할 수 있습니다.

예시

입력: a = 8, b = 16
출력: Yes

두 숫자의 이진 표현은 다음과 같습니다.
8  → 1000
16 → 10000

앞에 0을 채워 길이를 맞추면
8  → 01000
16 → 10000

두 문자열 모두 '0'이 4개, '1'이 1개로 구성되어 있으므로 아나그램입니다.

알고리즘

1단계 : 두 개의 숫자를 입력받습니다.
2단계 : bin() 함수를 사용해 각 숫자를 이진수 문자열로 변환합니다.
        이때 bin()의 결과에는 '0b' 접두사가 붙으므로 앞의 두 문자를 제거합니다.
3단계 : 두 이진 문자열의 길이가 다를 수 있으므로,
        더 짧은 문자열 앞에 '0'을 채워 길이를 동일하게 맞춥니다.
4단계 : Counter()로 각 이진 문자열을 딕셔너리(문자별 개수)로 변환한 뒤,
        두 딕셔너리를 비교합니다.
        '0'과 '1'의 개수가 모두 같으면 아나그램, 그렇지 않으면 아나그램이 아닙니다.

예제 코드

# 두 숫자의 이진 표현이
# 아나그램인지 확인하는 함수
from collections import Counter 

def anagramoftwonumber(p1, p2): 
   # 숫자를 이진수 문자열로 변환
   # bin() 함수의 출력에는 '0b' 접두사가 붙으므로
   # 앞의 두 문자를 제거합니다.
   bno1 = bin(p1)[2:] 
   bno2 = bin(p2)[2:] 
  
   # 더 짧은 문자열 앞에 0을 채워 길이 맞추기
   zeros = abs(len(bno1) - len(bno2)) 
   if (len(bno1) > len(bno2)): 
      bno2 = zeros * '0' + bno2 
   else: 
      bno1 = zeros * '0' + bno1 
  
   # 이진 표현을 딕셔너리(Counter)로 변환
   dict1 = Counter(bno1) 
   dict2 = Counter(bno2) 
  
   # 두 딕셔너리 비교
   if dict1 == dict2: 
      print(p1, p2, "는 서로 아나그램 관계입니다") 
   else: 
      print(p1, p2, "는 아나그램 관계가 아닙니다") 
  
# 메인 프로그램
if __name__ == "__main__": 
   n1 = int(input("첫 번째 숫자 입력 ::>"))
   n2 = int(input("두 번째 숫자 입력 ::>"))
   anagramoftwonumber(n1, n2)

실행 결과

첫 번째 숫자 입력 ::>8
두 번째 숫자 입력 ::>16
8 16 는 서로 아나그램 관계입니다

첫 번째 숫자 입력 ::>3
두 번째 숫자 입력 ::>2
3 2 는 아나그램 관계가 아닙니다

핵심 정리

이 문제의 핵심은 세 가지입니다. 첫째, bin() 함수로 숫자를 이진 문자열로 변환할 때 [2:] 슬라이싱으로 '0b' 접두사를 제거하는 것. 둘째, 길이가 다른 두 이진 문자열을 비교 가능하도록 앞쪽에 0을 패딩하는 것. 셋째, Counter 객체끼리 직접 비교(==)하면 각 문자의 등장 횟수까지 자동으로 비교해 주므로 별도의 반복문 없이 아나그램 여부를 판별할 수 있다는 점입니다.