본문 바로가기
Algorithm/자료구조와 함께 배우는 알고리즘

반복하는 알고리즘 (1)

by re-hwi 2022. 7. 15.

알고리즘을 잘 이해하기 위해서는 정말 문제를 많이 풀어봐야 하는 것 같다.

 

문제를 많이 풀어보면서 비슷한 유형의 문제가 나오면 풀었던 기억을 돌아보며 그 알고리즘에 대입하는 것도 좋은 방법이지만 새로운 방식을 이용하여 가장 좋은 알고리즘을 생각해내는 창의성인것 같다. 


문제 1. 1부터 n까지 정수의 합 구하기 

n = int(input('n값 입력 : '))

sum = 0
for i in range(1,n+1):
    sum += i
print(f'{sum}입니다')

이 방법은 내가 풀었던 방법이였는데 책에는 while을 이용한 방법도 있었다. 이 문제는 반복문의 기초를 배우기 위한 문제인것 같으므로 패스하겠다. ㅋ

 

문제 2. 연속하는 정수의 합 구하기

# 책에서 나온 코드

print('a부터 b까지 정수의 합을 구합니다.')

a = int(input('정수 a를 입력 :'))
b = int(input('정수 b를 입력 :'))

if a > b:   # 두 수중 큰 수 판별
    a,b = b,a

sum = 0
for i in range(a,b+1):
    if i < b:
        print(f'{i} + ', end = '')
    else :
        print(f'{i} = ',end = '')
    sum += i
print(sum)

 

# 내가 만든 코드

print('a부터 b까지의 합 구하기')

n = int(input('n값 입력 : '))
m = int(input('m값 입력 : '))

sum = 0

for i in range(n,m+1):
    sum += i
print(sum)

이 두 코드의 차이점은 먼저 내가 만든 코드는 두 수의 순서가 바뀌면 0을 출력한다. 항상 n이 m보다 작아야 하지만 책에서 나온 코드는 하나의 조건문을 이용해 두 수가 바뀌어도 판별을 하며 수행할 수 있기 때문에 조금 더 편리한 코드인 것 같다.

 

문제 3. +-를 번갈아가며 출력하기

print('+와 - 를 번갈아 출력합니다.')
n = int(input('몇번 출력할까요? :'))
for i in range(n):
    if i % 2 == 0:		# 홀수인 경우 + 출력
        print('+',end = '')
    else :
        print('-',end = '')	# 짝수인 경우 - 출력

이 코드는 원하는 결과를 얻을 수 있지만 for 문이 반복되는 내내 if 문이 수행된다는 점에서 비효울 적이다. 또한 상황에 따라 유연한 수정이 어렵다.

 

따라서 보완한 코드는 아래와 같다.

print("+와 - 번갈아가며 출력")
n = int(input('입력:'))

for i in range (n//2):	# n의 절반만큼 +-를 같이 출력
    print('+-',end='')

if n % 2 :		# 만약 n이 2로 나누어 떨어지지 않는다면 (홀수라면) 추가로 + 출력
    print('+',end='')

print()

문제 4. *을 출력하되 몇개 이후 줄바꿈을 할 것인가

# 내가 만든 코드

print('*을 출력합니다.')
star = int(input('별을 몇 개 출력할까요 :'))
line = int(input('몇 번째마다 줄바꿈을 할까요 :'))

for i in range(1, star // line + 1):
    print('*' * line)
if star % line != 0:  # 나누어떨어지지 않는다면
    print('*' * (star % line))

이 코드의 내용은 별을 출력하되 입력한 수만큼 별이 출력되었다면 줄바꿈을 해 아래에 별을 출력하는 코드이다.

 

나는 이 문제를 앞에서 나온 +- 순서대로 출력하기에 아이디어를 얻어 풀었다.

 

먼저 *의 개수를 입력받은 뒤 줄바꿈을 해야하는 값으로 나눈다. 이 때 몇 개의 줄을 만들어야할지 정할 수 있다. 하지만 이렇게 하면 마지막 줄은 나타내지 못한다.

 

그렇기 때문에 만약 별의 값과 줄바꿈의 값을 나누어 나머지가 생긴다면 (나누어 떨어지지않는다면) 그 나머지만큼 별을 출력한다.

 

문제 5. 사각형의 넓이를 입력받아 사각형의 가로 세로 길이를 만들 수 있는 경우의 수 구하기

area = int (input('직사각형의 넓이를 입력하시오 '))

for i in range(1, area+ 1):
	if i * i > area:
    	break
    if area % i :
    	continue
    print(f'{i} * {area // i}')

이 문제는 약수를 나열하는 문제이다.

 

코드의 내용은 만약 i * i 가 area를 초과한다면 for 문이 종료된다. i가 가장 긴 변이 되기 때문이다. 예를 들어 i가 5일 때 5*5는 25이므로 사각형의 최대 넓이를 초과하면서도 가장 긴 변의 길이가 된다.

 

또한 i 가 area에 나누어떨어지지 않는다면 (약수가 아니라면) 다시 for 문에 들어간다. 이런 조건을 반복하며 결국에는 약수만을 출력하는 코드이다. 

 

내가 추가로 리스트에 모든 약수를 담는 코드도 만들어 보았다.

# 가로 세로 길이가 정수이고 넓이가 area 인 직사각형에서 변의 길이 나열하기

width = int(input('가로 길이 입력 :'))
height = int(input('세로 길이 입력 :'))

area = width * height

my_list = []

for i in range(1,area+1):
    if area % i == 0:
        my_list.append(i)
        len_my_list = len(my_list)

print(my_list)
print('넓이 : ', area)

이 코드는 입력값이 넓이가 아닌 가로와 세로이다. 가로와 세로값을 입력해 얻은 넓이의 약수를 출력한다. 

 

먼저 가로 * 세로를 이용해 넓이를 구한다. 그 넓이가 1부터 area 사이에 있는 값으로 나누었을 때 나누어 떨어진다면 (약수라면) 리스트에 추가한다. 

 

이렇게 간단한 코드만을 추가하여 색다른 느낌의 코드를 만들 수 있는게 재미있는 것 같다.

 

문제 6. 두자리 수의 양수만 입력받기

while True:
    no = int(input('값을 입력하시오 : '))
    if no >= 10 and no <= 99:	# no가 10 이상이고 99 이하일때 무한반복을 멈춤
        break	

print(no)

 and 연산자를 이용한 프로그램이다. and는 두 조건중 하나라도 거짓일 시 false를 반환한다. 따라서 두 조건중 모두 참일 때 break 가 실행이 된다.

반응형

댓글