알고리즘

[Python & SQL] 약수 구하기

LeeSeunghyuk 2020. 12. 28. 12:56
반응형

 

안녕하세요 

 

알고리즘 첫 번째 게시물 입니다.

 

입력받은 숫자 혹은 숫자 자료의 약수를 구하는 방법을 알아보도록 하겠습니다.

 

약수(divisor)

 

     divide : 나누다 + or : 접미사

 

     즉, 해석하면 " 나누는 역할을 하는 것 " 정도로 해석이 됩니다.

 

     - 어떤 정수(d)를 0이 아닌 정수(n)로 나누어 떨어졌을 때

     - 어떤 정수(d)를 0이 아닌 정수(n)로 나누었을 때 나머지가 0

     

     이때 , 정수(n)은 정수(d)의 약수입니다.

 

     1은 0이 아닌 모든 정수의 약수이고 , 어떤 수의 자기 자신또한 약수입니다.

 

 

정수(Integer)

 

     정의 : 자연수 , 0 , 음의 기호(-)를 붙인 자연수 

 

     자연수는 1, 2, 3 처럼 세는 수(counting number) 라고도 합니다.

 

     즉, 정수는 "  - ∞ ~ + , 1 의 간격 "  이라고 할 수 있습니다.

 


 

약수와 정수의 개념에 대해서 간단하게 알아보았습니다.

Python , Oracle SQL 언어를 통해 약수 구하는 코드를 구현해 보도록 하겠습니다.

 

- 접근 방식

 

     1. 사용자로부터 수를 입력 받는다.

     2. 정수인지 판별한다.

     3. 입력 받은 수를 1부터 입력받은 수 까지 나누는 코드를 구현한다.

     4. 나머지가 0인 경우 약수 리스트로 지정, 출력한다.

 

 

### Python 약수 구하기

 

     간단하게 작성하면 다음과 같이 작성할 수 있습니다.

d=input('숫자를 입력하세요 :') # 사용자에게 숫자 입력 받습니다

if '.' in d:                   # 받은 숫자가 정수인지 판단합니다.
    print('정수가 아닙니다.')  # 간단하게 작성해서 소수점의 유/무로 정수를 판단합니다.
    
else:
    d=int(d)                   # 입력 받은 숫자는 문자열 객체이므로 숫자 데이터로 변환합니다.
    divisor_list=[i for i in range(1,d+1) if d%i==0] # comprehension 문법을 사용 
                                                     # for 문을 통해 반복 인자와 나머지 기호(%) 사용
    print(divisor_list)

 

※ 위 코드의 문제점 ?

 

         정수도 유리수처럼 표현이 가능합니다.

 

         ex) 5.0 15.0 ...

 

         다음과 같이 코드를 수정해 보았습니다.

import math
d=input('숫자를 입력하세요 : ')

if float(d)-math.trunc(float(d))==0:
    d=int(float(d))
    divisor_list=[i for i in range(1,d+1) if d%i==0]
    print(divisor_list)
    
else:
    print('정수가 아닙니다.')

 

입력받은 문자열이 24.9 입니다. 

" 숫자 자료형 " 24.9는 int() 함수로 형변환 하면 24로 바뀝니다.

 

24.9라는 " 문자열 " 은 int 형으로 바꿀 수 없습니다. 

 

' . ' --> 소수점 문자를 숫자로 바꿀 수 없기 때문입니다.

 

파이썬 내장 모듈 math를 import 했습니다.

 

입력받은 문자를 float() , math.trunc(float()) 로 연산합니다.

 

24.9 - 24 라는 계산을 수행하여 0인 경우에만 약수 구하는 연산을 수행합니다!


 

### Oracle SQL 약수 구하기

 

고민 없이 바로 작성한 코드는 다음과 같습니다.

 

accept d prompt '숫자를 입력하세요 :'

select &&d 수, case when &&d-trunc(&&d)=0 then to_char(level)
                                   else '정수가 아닙니다.' end 약수
from dual
where mod(&&d,level)=0
connect by level<=&&d;

18.0을 입력한 결과입니다.

 

역시 처음 작성한 코드는 항상 문제가 있는 것 같습니다.

 

 ※ 위 코드의 문제점 ?

 

정수가 아닌 수를 입력하면 출력되는 내용이 없습니다.

 

 

다음과 같이 코드를 수정했습니다

accept d prompt '숫자를 입력하세요 :'

select &&d 수,case when &&d-trunc(&&d)=0 then listagg(to_char(decode(mod(&&d,level),0,level)),',')
                                   else '정수가 아닙니다.' end 약수
from dual
connect by level<=&&d;

원하는 결과가 잘 출력되었습니다.

 

decode를 통해 나머지가 0이면 나누는 수를 출력합니다

--> decode(   mod(&&d ,level)      ,     0    ,     level)

                   d나누기 level나머지    0이면       level 출력

 

else 문의 출력 내용이 문자형이므로 약수도 문자형으로 출력하기 위해 형변환 합니다.

--> to_char ( decode(mod(&&d ,level),0,level) )

 

전체 결과를 가로로 보기 위해서 listagg 함수를 사용합니다. 구분자는 콤마(,)로 했습니다.

--> listagg( to_char(decode(mod(&&d,level),0,level)),',' )

 

 

오늘은 수를 입력받고 그 수가 정수인지 판별한 후 약수를 구하는 코드를 구현해 보았습니다.

 

읽어주셔서 감사합니다!

 

더 나은 방법이 있다면 댓글로 공유해주시면 감사하겠습니다.

반응형