문제

0과 1로 이루어진 어떤 문자열 x에 대한 이진 변환을 다음과 같이 정의한다.

1. 0을 모두 제거한다.

2. x의 길이를 c라고 할 때, x를 'c를 이진법으로 표현한 문자열'로 바꾼다.

 

문자열 s가 주어질 때, s가 '1'이 될 때까지 이진 변환을 계속 했을 때

이진 변환의 횟수와 이 때 제거된 0의 개수를 반환하는 함수를 만들어야한다.

 

 

제한조건

1. s의 길이는 1 이상 150000 이하이다.

2. s에는 '1'이 최소 하나는 들어있다.

 

 

코드

def solution(s):
    em_zero_count = 0
    i_num = 0

    def bin_func(s):
        nonlocal em_zero_count
        nonlocal i_num

        if s == '1':
            return
        
        new_s = ''
        for character in s:
            if character == '1':
                new_s += '1'
            else:
                em_zero_count += 1
        i_num += 1
        
        return bin_func(format(len(new_s), 'b'))
    
    bin_func(s)

    return [i_num, em_zero_count]

 

 

설명

em_zero_count = 0
i_num = 0

em_zero_count는 제거된 0의 개수, i_num은 이진변환횟수를 나타내는 변수들이다.

 

 

def bin_func(s):
	nonlocal em_zero_count
	nonlocal i_num

	if s == '1':
		return
        
	new_s = ''
	for character in s:
		if character == '1':
			new_s += '1'
 		else:
			em_zero_count += 1
	i_num += 1
        
	return bin_func(format(len(new_s), 'b'))

이진 변환 함수이다. 재귀함수의 구조로 되어있다.

 

nonlocal em_zero_count
nonlocal i_num

nonlocal을 통해 이 함수 바로 밖에 있는 각 이름에 해당하는 변수를 사용하도록 해준다.

 

if s == '1':
	return

재귀함수에서 가장 중요한 탈출 조건이다.

문제에서 제시한것 처럼 s가 '1'이 되면 종료한다.

 

new_s = ''
for character in s:
	if character == '1':
		new_s += '1'
	else:
		em_zero_count += 1
i_num += 1

메인 로직으로 문자열 s의 문자 하나씩을 꺼내며 반복한다.

문자가 '1'이면 new_s문자열에 '1'을 더해준다.

'0'일 경우 em_zero_count에 1을 더해준다.

 

이 반복문이 종료되면 이진 변환 한 번이 종료되었다는 뜻으로

i_num에 1을 더해준다.

 

return bin_func(format(len(new_s), 'b'))

new_s의 길이를 format함수를 통해 이진변환해준다. 0b는 제거하도록 한다.

이진변환한 문자열을 다시 bin_func에 넣어 재귀하도록 한다.

 

 

bin_func(s)

바깥 함수에서 만들어둔 bin_func를 호출한다.

 

 

return [i_num, em_zero_count]

bin_func의 동작이 끝나면 i_num과 em_zero_count는 각각 이진 변환 횟수와 제거된 0의 개수로 바뀌어있다.

그 값들을 리스트의 형태로 반환한다.