반응형

안녕하세요.

 

블로그를 개설하고 처음으로 방명록에 질문이 올라왔습니다.

 

파이썬 관련된 코딩 문제 인데요.

 

구현해야 되는 내용은 다음과 같습니다.

 

1. shorthead (sentence) 함수를 작성

 

2. shorthead의 인자인 sentence는 임의의 문자열

 

3. shorthead는 문자열을 입력 받고, 해당 문자열 안에서 반복되는 문자열이 있으면 해당 문자열과 반복되는 횟수를 출력. 반복되는 문자열이 없으면 입력했던 문자열을 그대로 출력

 

입니다.

 

 

이 함수의 입력, 출력 예시 입니다.

 

예시 1) shorthand('ABABABABABABABABABABABABABABABABABAB')

'(AB)_18'

 

예시 2) shorthand('ABABBAAAABBBABABBAAAABBBABABBAAAABBB')

'(ABABBAAAABBB)_3'

 

예시 3) shorthand('ABABBAAAABBBABABBAAAABBBBBABBAAAABBB')

'ABABBAAAABBBABABBAAAABBBBBABBAAAABBB'

 

 

질문자 분께서 올려주신 코드는 다음과 같습니다.

 

 

1 def shorthead(sentence):
x = len(sentence)
3 for i in range(1, (len(sentence)//2)+1):
4 s = sentence[0:i]
5 count = int(len(sentence)/len(s))
6 if (s*(x//i) == sentence):
7 return '('+s+')'+'_'+str(count)

 

위 코드를 실행 하였을 때, 예시 1과 예시 2는 제대로 출력이 되는 반면,

 

예시 3, 즉 입력된 문자열 안에 반복되는 문자열이 없는 경우가 제대로 출력되지 않아 질문을 올리셨다고 합니다.

 

 

위 코드를 분석해보면, 먼저 for 문을 사용해서 변수 i에 1부터 입력된 문자열의 길이의 반 만큼 반복을 합니다.

 

4번째 줄에선 변수 s에 입력된 문자열 sentence의 앞 i 개의 글자를 저장합니다.

 

그리고 count라는 변수에는 sentence의 길이를 s의 길이로 나눠 s가 몇 번 반복되야 i가 되는지를 확인합니다.

 

마지막으로 6번째줄에서 문자열 s를 i회 반복 하였을 때, 처음 입력한 문자열이 나오는지 비교를 하고,

 

만약 처음 입력한 문자열과 같다면, 반복되는 문자열 s와 그 횟수를 출력합니다.

 

 

위 코드에는, 

 

만약 반복되는 문자열이 없을 경우, 입력한 문자열을 그대로 출력하는 부분이 없습니다.

 

그래서 반복되는 문자열이 있는 예제 1과 예제 2는 제대로 출력이 되는 반면,

 

반복되는 문자열이 없는 예제 3 같은 경우에는 제대로 출력이 안되는 것 입니다.

 

 

이 코드의 한 줄만 추가하면 원하는 동작을 하는 함수를 작성할 수 있습니다.

 

 

1 def shorthead(sentence):
x = len(sentence)
3 for i in range(1, (len(sentence)//2)+1):
4 s = sentence[0:i]
5 count = int(len(sentence)/len(s))
6 if (s*(x//i) == sentence):
7 return '('+s+')'+'_'+str(count)
return sentence

 

8번째 줄에 for 문을 벗어나면 처음 입력했던 문자열을 return 하는 내용을 추가하였습니다.

 

이렇게 하면 반복되는 문자열이 없을 떄엔 입력한 문자열을 그대로 출력하는 동작을 하게 됩니다.

 

 

우선 이렇게 하면 함수는 원하는 동작을 합니다.

 

하지만 좋은 코드라고는 볼 수 없을 것 같습니다.

 

몇 가지 수정을 해보겠습니다.

 

 

1 def shorthead(sentence):
x = len(sentence)
3 for i in range(1, (x // 2)+1):
4 s = sentence[0:i]
5 count = int(x / i)
6 if (s*count == sentence):
7 return '('+s+')'+'_'+str(count)
return sentence

 

 

위 코드에서 3번, 5번, 6번 라인에 약간의 변화를 주었습니다.

 

 

3번 라인부터 보겠습니다.

 

코드의 2번 라인에서 x라는 변수에 입력된 문자열 sentence의 값을 저장하였습니다.

 

그런데 3번 라인에서 2번 라인과 동일하게 작성된 부분이 있습니다.

 

그래서 3번라인의 len(sentence) 를 x 로 바꿔주었습니다.

 

시간을 조금이라도 줄이기 위해 함수의 호출은 최대한 줄이는 것이 좋습니다.

 

 

5번 라인 역시 동일한 이유로 len(sentence)를 x로 바꾸어주었습니다.

 

그리고 5번 라인에는 문자열 s의 길이를 구하는 len() 함수의 호출이 한번 더 있습니다.

 

하지만 굳이 s의 길이를 len() 함수를 사용하여 구할 필요는 없는 것 같습니다.

 

왜냐하면 반복문에서 사용한 변수 i가 문자열 s의 길이이기 때문입니다.

 

때문에 len(s)를 i로 바꾸어주었습니다.

 

 

마지막으로 6번째 줄에서 'x//i'의 값을 5 번째 줄에서 구한 count 라는 값으로 변경해주었습니다.

 

사칙 연산의 결과를 변수에 저장을 하였기 때문에, 굳이 동일한 사칙 연산을 다시 할 필요가 없습니다.

 

 

기본적인 중복 내용을 제거 하여 아주 조금 더 빠르게 끝나는 코드를 작성하였습니다.

 

 

마지막으로 성능을 조금 더 올려보겠습니다.

 

위 코드에서는 입력된 문자열의 길이가 N이라면, for 문을 N/2 회 반복합니다.

 

즉, 극단적으로 문자열의 길이가 10000인 문자열이 입력된다면 for 문을 5000회 반복하게 됩니다.

 

만약 반복되는 문자열이 없는 길이가 10000인 문자열이 입력 된다면,

 

5000회 동안 4~6번 라인을 반복한 후, for문을 벗어나 기존에 입력한 변수를 return 하게 됩니다.

 

여기에 if 문 하나를 추가해서 조금 시간을 더 줄여보도록 하겠습니다.

 

 

1 def shorthead(sentence):
x = len(sentence)
3 for i in range(1, (x // 2)+1):
4 if(x % i == 0):
5 s = sentence[0:i]
6 count = int(x / i)
7 if (s*count == sentence):
8 return '('+s+')'+'_'+str(count)
return sentence

 

4번 라인을 추가하였습니다.
 
입력된 문자열의 길이 x를, 비교 할 문자열의 길이 i로 나누었을 때 나누어 떨어지는 경우, 즉 나머지가 0인 경우만 밑의 코드를 실행하게 해보았습니다.
 
만약 전체 길이가 40인 문자열이 입력 된다면,
 
i가 1, 2, 4, 5, 8, 10, 20 일 때, 즉 7번만 밑의 과정이 실행됩니다.
 
해당 조건문이 없다먼 1~20, 즉 20번이 실행이 되겠지요.
 
대신 x % i == 0 인지 확인하는 작업이 한번 더 늘어났습니다.
 
경우에 따라선 이 구문을 추가하였을 때 시간이 더 걸릴 수도 있겠습니다.
 
하지만 일반적인 경우 위의 코드가 조금 더 빠르게 돌아갈 것 같습니다.
 
 
처음 생각으로는 for 문을 실행할 때 i의 값을 x의 반 이하인 x의 약수 들만 대입하려고 하였으나...
 
파이썬의 기본 함수로 x의 약수를 구하는 함수를 찾지 못하였습니다.
 
(찾아보면 있을 것도 같긴 한데... 아직 저도 파이썬 초보라...ㅜ)
 
 
이 질문을 보고 깨달은 것은 파이썬이 상상 이상으로 편한 코드구나 라는 것 입니다.
 
C를 주로 사용했던 저로써는 

 

if (s*count == sentence)

 

란 내용을 떠올리기가 쉽지 않았습니다.

 

아직 배워야 할 것이 많습니다...ㅜㅜ

 

 

혹시 위 코드를 더 좋게 바꿀 수 있다면 내용 추가하도록 하겠습니다.

 

더 좋은 내용이 있으면 댓글 부탁드립니다.

 

감사합니다.

반응형
Posted by 해리팍
BLOG main image

Chanhyun Park (해리팍)
Software Engineer @ SK hynix

Contact Info.
parkch0708@hanmail.net
chanhyun0708@gmail.com
chanhyun.park@sk.com

카테고리

All (1501)
Profile (2)
Park's Life (599)
Computer System (165)
Computer Programming (39)
Computer Study (54)
Computer Etc. (189)
Scuba Diving (137)
Golf (8)
Traveling (245)
생활 정보 (12)
Pokemon GO (50)