[COS Pro 1급 Python] 1차 기출문제 2) 해밍 거리 구하기

정은·2023년 7월 22일

COS Pro 1급

목록 보기
3/26
post-thumbnail

문제 2)

해밍 거리(Hamming distance)란 같은 길이를 가진 두 개의 문자열에서 같은 위치에 있지만 서로 다른 문자의 개수를 뜻합니다. 예를 들어 두 2진수 문자열이 "10010"과 "110"이라면, 먼저 두 문자열의 자릿수를 맞추기 위해 "110"의 앞에 0 두개를 채워 "00110"으로 만들어 줍니다. 두 2진수 문자열은 첫 번째와 세 번째 문자가 서로 다르므로 해밍 거리는 2입니다.

  • 1 0 0 1 0
  • 0 0 1 1 0

두 2진수 문자열 binaryA, binaryB의 해밍 거리를 구하려 합니다. 이를 위해 다음과 같이 간단히 프로그램 구조를 작성했습니다

1단계. 길이가 더 긴 2진수 문자열의 길이를 구합니다.
2단계. 첫 번째 2진수 문자열의 길이가 더 짧다면 문자열의 앞에 0을 채워넣어 길이를 맞춰줍니다.
3단계. 두 번째 2진수 문자열의 길이가 더 짧다면 문자열의 앞에 0을 채워넣어 길이를 맞춰줍니다.
4단계. 길이가 같은 두 2진수 문자열의 해밍 거리를 구합니다.

두 2진수 문자열 binaryA와 binaryB가 매개변수로 주어질 때, 두 2진수의 해밍 거리를 return 하도록 solution 함수를 작성했습니다. 이때, 위 구조를 참고하여 중복되는 부분은 func_a라는 함수로 작성했습니다. 코드가 올바르게 동작할 수 있도록 빈칸을 알맞게 채워 전체 코드를 완성해주세요.


매개변수 설명

두 2진수 문자열 binaryA와 binaryB가 solution 함수의 매개변수로 주어집니다.

  • binaryA의 길이는 1 이상 10 이하입니다.
  • binaryA는 0 또는 1로만 이루어진 문자열이며, 0으로 시작하지 않습니다.
  • binaryB의 길이는 1 이상 10 이하입니다.
  • binaryB는 0 또는 1로만 이루어진 문자열이며, 0으로 시작하지 않습니다.

return 값 설명

두 2진수 문자열의 해밍 거리를 return 해주세요.


예시
binaryAbinaryBreturn
"10010""110"2
예시 설명

두 2진수의 자릿수는 각각 5와 3입니다. 자릿수를 맞추기 위해 "110" 앞에 0 두 개를 채워주면 "00110"이 됩니다. 이제 두 2진수 문자열의 해밍 거리를 구하면 다음과 같습니다.

  • 1 0 0 1 0
  • 0 0 1 1 0

위와 같이 첫 번째와 세 번째 문자가 서로 다르므로, 해밍 거리는 2가 됩니다.

주어진 문제 2) 코드

def func_a(string, length):
    padZero = ""
    padSize = @@@
    for i in range(padSize):
        padZero += "0"
    return padZero + string

def solution(binaryA, binaryB):
    max_length = max(len(binaryA), len(binaryB))
    binaryA = func_a(binaryA, max_length)
    binaryB = func_a(binaryB, max_length)
    
    hamming_distance = 0
    for i in range(max_length):
        if @@@:
            hamming_distance += 1
    return hamming_distance

#The following is code to output testcase.
binaryA = "10010"
binaryB = "110"
ret = solution(binaryA, binaryB)

#Press Run button to receive output. 
print("Solution: return value of the function is", ret, ".")

Solution

주어진 문제 2) Solution 코드

def func_a(string, length):
    padZero = ""
    padSize = length - len(string)
    for i in range(padSize):
        padZero += "0"
    return padZero + string

def solution(binaryA, binaryB):
    max_length = max(len(binaryA), len(binaryB))
    binaryA = func_a(binaryA, max_length)
    binaryB = func_a(binaryB, max_length)
    
    hamming_distance = 0
    for i in range(max_length):
        if binaryA[i] != binaryB[i]:
            hamming_distance += 1
    return hamming_distance

#The following is code to output testcase.
binaryA = "10010"
binaryB = "110"
ret = solution(binaryA, binaryB)

#Press Run button to receive output. 
print("Solution: return value of the function is", ret, ".")

문제 2) Solution 전체 코드 [본인 작성]

def func_a(string, length): # 길이가 짧으면 문자열 앞에 0을 넣어주는 함수
    padZero = ''
    for i in range(length - len(string)):
        padZero += '0'
    return padZero + string 

def solution(binaryA, binaryB):
    max_length = max(len(binaryA), len(binaryB)) # 1. 문자열 길이 중 더 큰 길이 구하기
    binaryA = func_a(binaryA, max_length) # 2. 첫번째 문자열이 짧을 때 0을 추가하기
    binaryB = func_a(binaryB, max_length) # 3. 두번째 문자열의 길이가 짧을 때 0 추

    hamming_distance = 0
    for i in range(max_length):
        if binaryA[i] != binaryB[i]: # 4. 길이가 같은 두 2진수의 해밍 거리: 각 자리를 비교해 서로 다른 경우의 개
            hamming_distance += 1                     
    return hamming_distance

#The following is code to output testcase.
binaryA = "10010"
binaryB = "1110"
ret = solution(binaryA, binaryB)

#Press Run button to receive output. 
print("Solution: return value of the function is", ret, ".")

알고 있으면 좋은 함수💡

파이썬 리스트를 활용하는 함수 : enumerate()

enumerate()은 리스트의 각 항목들을 (인덱스, 항목 값) 튜플 형태로 가져오는 함수를 말한다.

사용 예를 보자.

x = ['a', 'b', 'c']

e = list(enumerate(x))
print(e)
>>> [(0, 'a'), (1, 'b'), (2, 'c')]
  • enumumerate() 함수를 사용하여 리스트 변수 x의 인덱스와 항목 값을 튜플로 가져와 리스트로 변환한다.
x = ['a', 'b', 'c']

for i, v in enumumerate(x):
	print(i, v)
    
>>>
0 a
1 b
2 c
  • enumumerate() 함수로 가져온 리스트 변수 x의 인덱스와 항목 값을 for문을 이용하여 변수 i, v로 받아서 출력한다.

파이썬 리스트를 활용하는 함수 : zip()

zip()은 두 개 이상의 리스트를 같은 인덱스 항목끼리 묶어 튜플 형태로 구성하여 한꺼번에 가져오는 함수를 말한다.

사용 예를 보자.

x1 = [1, 2, 3]
x2 = [4, 5, 6]

z = list(zip(x1, x2)))
print(z)
>>> [(1, 4), (2, 5), (3, 6)]
  • zip() 함수를 사용하여 리스트 변수 x1, x2를 같은 인덱스의 항목끼리 묶어 튜플로 가져온 객체를 리스트로 변환한다.
x1 = [1, 2, 3]
x2 = [4, 5, 6]

for a, b in zip(x1, x2):
	print(a, b)
>>> 
1 4
2 5
3 6
  • zip() 함수로 가져온 리스트 변수 x1과 x2의 항목값을 for문을 이용하여 변수 a,b로 받아서 출력한다.

파이썬 특징을 살려 코딩을 해보자❗

1) 문자열을 2진수로 변환 후 해밍 거리 구하기 : zip() 함수 사용

# 1) 문자열을 2진수로 변환 후 해밍 거리 구하기
x="10010"
y="110"

max_length = max(len(x), len(y)) # 긴 문자열의 길이 구하기 

x = '0' * (max_length - len(x)) + x # 부족한 자리 0으로 채우기
y = '0' * (max_length - len(y)) + y # 부족한 자리 0으로 채우기

cnt = 0
for a, b in zip(x, y):
    if a != b:
        cnt += 1

print(cnt)
>>> 2
  • zip() 함수를 이용하여 문자를 하나씩 가져와 값을 비교하는 방식을 사용하였다.
  • 여기서, 문자열을 채우는 방식은 파이썬의 특징을 살려 문자열 * 숫자를 하면 문자열이 이어붙어진다는 점을 토대로 작성하였다.

2) 십진수를 2진수로 변환 후 해밍 거리 구하기 : 비트 연산 사용

x1 = 18; x2 =6
print(bin(x1^x2).count('1'))
>>> 2
  • x1과 x2에 대해 XOR(^) 연산을 한 결과값을 2진수로 변환하여 나오는 수에서 1의 개수를 구하여 출력한다.
    • 여기서 말하는 XOR 연산은 서로 다른 값일 때에는 True(1)이고 서로 같은 값일 땐 False(0)로 나타나는 연산을 말한다.

      ex) 1 0 => 1 | 0 0 => 0

Tip ❗

  • count() 함수 내에 들어가는 값은 꼭 문자열 '1'이어야 한다. bin 함수로 되는 것은 문자열로 표현되기 때문!

3) 문자열을 2진수로 변환 후 해밍 거리 구하기 : 비트 연산 사용

x="10010"
y="110"

x = int(x, 2)
y = int(y, 2)

print(bin(x^y).count('1'))
  • int() 함수를 이용하여 문자열 x, y를 2진수로 변환한다. int(문자열, 진수법)
  • 위와 동일하게 XOR(^) 연산을 한 결과 값을 2진수로 변환하여 나오는 결과(bin())에서 1의 개수를 구하여 출력한다.
profile
정니의 이런거 저런거 기록 일지 😛

2개의 댓글

comment-user-thumbnail
2023년 7월 22일

해밍 거리에 대해 새로운 지식을 알게 되어 유익했습니다. 저도 비트 연산에 대해 좀 더 알아봐야겠네요. 감사합니다!

1개의 답글