10. Python 기초이기 보다는 전반적인 알고리즘
이제 코딩을 어느 정도 배웠으니 알고리즘에 대해서 설명하겠습니다. 솔직히 알고리즘 (Algorithm)이라는 말을 많이 들어 보았을 것이고, 코딩을 하면 알고리즘을 만든다 이렇게 알고 있을 겁니다. 네 맞습니다. 알고리즘이라고 하면 어떤 문제를 풀기 위한 여러 단계를 생각하시면 됩니다. 코딩을 하는 이유는 어떤 문제를 해결하기 위해서 하니까 코딩을 해서 알고리즘을 한다고 보면 되겠네요. 그러면 알고리즘을 코딩할 때 생각해야 하는 부분은 무엇일까요? 당연히 첫 번째는 문제 해결이 되냐 안되냐입니다. 코딩을 했는데 문제 해결이 안 되면 뭐 의미가 없는 거니까요. 두번째로는 문제를 푸는 데 있어서 얼마나 시간이 걸리냐입니다. 당연한 거지만, 일반적으로 살아가는데 어떤 곳에서도 시간이 오래 걸려서 문제를 풀면 좋아하지 않습니다. 예를 들어서, 파스타 집에서 파스타를 주문했는데 시간이 3시간 걸려서 나온다면 아무도 그 파스타 집을 가지 않겠죠? 마찬가지로 알고리즘도 문제 해결하는데 시간이 얼마나 걸리는지가 생각을 해야 합니다. 세번째로 얼마만큼의 메모리를 사용했냐입니다. 메모리가 무한하지 않기 때문에 메모리를 마음대로 막 사용하게 되면 프로그램 속도 저하 문제가 생길 수도 있고 팅기는 경우도 발생할 수 있습니다. 그렇기 때문에 한정적인 메모리 안에서 효율적으로 사용하기 위해서 알고리즘을 잘 구현해야 합니다. 물론, 간단한 코딩 예를 들어서 숙제나 과제 정도면 크게 일반적으로 상관은 없습니다. 하지만, 계속 코딩을 이용해서 알고리즘을 개발하는 일을 하실 생각이라면 꼭 속도와 메모리 사용을 생각하면서 알고리즘을 구현하면 좋습니다.
이제부터 간단한 알고리즘(프로젝트나 여러 곳에서 구현되어서 사용되는 알고리즘)을 알려드리겠습니다. 이 밑으로 나오는 내용이 대단한 뭔가 그런 것이기보다는 여러 프로젝트를 하면서 이런 알고리즘을 함수화 해서 사용하는 경우가 많았던 경험이 있어서 간단하게 정리 및 예시를 보여 드리려고 합니다. (저 같은 경우는 처음 프로젝트 참여할 때, 처음으로 한 일이 간단하면서 프로젝트 참여한 사람들이 쓸 것 같은 함수들을 대충 만들어서 저장하는 것을 했는데 그 경험을 바탕으로 설명하겠습니다.)
처음으로는 가장 큰 수 혹은 가장 작은 수 찾는 알고리즘입니다. 정말 간단합니다. 반복문을 돌려서 처음부터 끝까지 모든 숫자를 확인을 해서 제일 큰 값 혹은 제일 작은 값을 찾는 알고리즘입니다. 반복문 하나 조건문 하나만 있으면 쉽게 해결이 되는 알고리즘입니다.
예시
input_data = [2,5,10,3,9,0,100]
def FindMax(input_data):
max_data = -1
for i in range(0,len(input_data)):
if(max_data < input_data[i]):
max_data = input_data[i]
return max_data
Ans = FindMax(input_data)
print(Ans)
출력 결과
위에 예시는 몇 가기 조건이 들어갑니다. 입력 값이 언제나 양수이다, 그리고 최대 값이 되는 것이 하나이다입니다. 그냥 최댓값만 찾는 거면 위에처럼 구현하면 되지만, 프로젝트할 때 저렇게 하면 좋지 않더라고요. 첫째 입력 값에 제한이 있다입니다. 예를 들어서 음수만 존재하는 입력이면 사용이 안됩니다. 그러면 사람들이 이것 안 쓰고 자기들이 알아서 만들어서 쓰겠죠? 그럼 여러분이 하는 일은 의미가 없어집니다. 그러니 구현을 할 때에는 여러 가지 생각을 하면서 다른 사람들이 어떻게 하면 쉽게 쓰고 원하는 정보를 다 줄 수 있을까 생각을 하면서 구현을 해야 합니다.
예시
input_data = [2,5,10,3,9,0,100]
input_data1 = [-2,-5,-10,-3,-9,-100]
def BetterFindMax(input_data):
max_data = input_data[0]
for i in range(1,len(input_data)):
if(max_data < input_data[i]):
max_data = input_data[i]
return max_data
Ans = BetterFindMax(input_data)
print(Ans)
Ans = BetterFindMax(input_data1)
print(Ans)
출력 결과
위에처럼 하면 입력 값이 음수만 들어가도 문제없이 사용이 가능합니다. 하지만 저것도 좀 아쉬는 부분이 있습니다. 예를 들어서 최대 값이 어느 index에 들어있는지 알고 싶은 경우에는 저 함수로는 알 수가 없습니다. 그렇다고 하면 index값도 같이 주면 더 좋지 않을까요?
예시
input_data = [2,5,10,3,9,0,100]
input_data1 = [-2,-5,-10,-3,-9,-100]
def MoreBetterFindMax(input_data):
max_data = input_data[0]
index = 0
for i in range(1,len(input_data)):
if(max_data < input_data[i]):
max_data = input_data[i]
index = i
return max_data, index
Ans, index = MoreBetterFindMax(input_data)
print("Value : %d, Index : %d" %(Ans, index))
Ans, index = MoreBetterFindMax(input_data1)
print("Value : %d, Index : %d" %(Ans, index))
출력 결과
이렇게까지 하면 얼추 사람들이 사용하는 경우가 발생할 것입니다. 하지만 이것도 좀 예외적인 부분을 해결 못하는 경우가 있습니다. 예를 들어서 값이 같은 것이 여러 개 존재하는 경우에는 문제가 발생할 수 있습니다. 그럼 Duplicate까지 확인 가능하면 위에 알고리즘보다 더 좋은 알고리즘이 나오지 않을까요?
예시
출력 결과
만약 최댓값이 같은 것이 없으면 리스트 길이가 1개짜리로 나올 것이고 여러 개면 여러 개 나올 것입니다. 이렇게 하면 최대 값을 찾는데 필요한 정보를 최대한으로 줄 수 있는 것 같습니다. 위에 보시면 마지막에 if문을 추가했는데, 그건 최초에 들어가는 리스트 처음 값이 최대일 경우에 index 값을 넣기 위해서 추가했습니다. 지금 위에 있는 코드가 최대 값을 찾는데 최고의 알고리즘이라고 할 수는 없습니다. 더 똑똑하고 훌륭한 개발자 분들이면 얼마든지 더 좋은 알고리즘을 만들 수 있을 겁니다. 여기서 제가 하고 싶은 이야기는 개발자로 일을 하게 되면 자기가 개발한 알고리즘을 사용하는 다른 개발자를 생각하면서 알고리즘을 만들라는 것입니다. 아무래도 학교나 학원에서 수업을 듣기만 하면 이런 부분에 대해서 자세히 설명이 없이 그냥 단순하게 빠르고 메모리 적게 사용하는 알고리즘을 만들면 좋다고만 하고 끝납니다. 물론 100번 1000번 맞는 말이지만, 개발자로 가실 분 혹은 가는 분들이라면 그 부분들도 당연히 생각을 해야 하고 또 이 알고리즘을 사용하게 될 다른 개발자들을 생각해서 더 쓰기 편하고 원하는 정보를 다 구할 수 있게 하는 것도 꼭 고려해야 합니다. 처음 최댓값 찾는 것처럼 그냥 답하나 구해주는 것만 보지 마시고, 이런 알고리즘을 왜 쓰는지 물어보고 사용을 하는 용도 및 어떤 입력 값을 쓰는지 확인을 해서 알고리즘 사용할 개발자가 쓰기 편하게 만드시기 바랍니다. 뭐 정말 너무 훌륭한 알고리즘이라 그 누구라도 내가 쓴 알고리즘을 쓰는 개발을 하시면 다른 개발자 분들이 여러분의 알고리즘에 맞게 하겠지만, 저 같은 경우는 다른 개발자들의 편의를 맞추는 경우가 많았습니다. 처음 시작하는 개발자들은 저와 비슷할 것이라고 생각이 듭니다. 위에 문제를 최대 값 찾는 것 대신 최소 값 찾는 알고리즘으로 만들어 보세요. 아마 아주 쉽게 만들 수 있을 것이라고 보고 다음으로 넘어가겠습니다. (아 Python인 경우에는 최대 최솟값 찾아주는 함수가 있습니다. 그것 사용해도 되겠네요.)
최댓값 최솟값을 찾는 것을 했으니 비슷한 값을 찾는 Searching을 하는 알고리즘을 보겠습니다.
이 경우에는 위에 설명한 최대 최솟값과 비슷한데 그 이유는 최댓값을 내가 알고 있는 상황에서 이 값이 이 리스트에 있나 없나 확인하는 것이기 때문에 매우 비슷합니다. 그래서 반복문과 조건문이 하나씩 필요합니다. 위에 알고리즘과 다른 점은 입력 값으로 찾고 싶은 값이 하나 더 들어간다는 것입니다.
예시
input_data = [2,5,10,3,9,100,100]
def FindSomeValue(input_data, value):
index = []
flag = -1
for i in range(0,len(input_data)):
if(value == input_data[i]):
index.append(i)
flag = 1
return flag, index
flag, index = FindSomeValue(input_data, 50)
print("Value : %d, Index : %s" %(flag, index))
flag, index = FindSomeValue(input_data, 3)
print("Value : %d, Index : %s" %(flag, index))
출력 결과
이렇게 하시면 Searching 문제를 알고리즘을 이용해서 잘 해결을 할 수 있습니다. Flag 값이 -1일일 때 존재하지 않는 것이고, 1인 경우에는 리스트 안에 존재한다는 것을 알 수 있습니다. 그리고 그 값이 어느 index에 존재하는지 알 수도 있습니다. 또한, 같은 값을 가진 index가 여러 개인 경우에도 다 확인이 가능합니다.
많은 예를 보여 드리고 싶지만, 한 글에 너무 많은 글이 써져서, 다음 글에 이어서 다른 알고리즘에 대해 설명하겠습니다. 다시 말씀드리지만, 이번 글은 제 경험에서 쓴 거라서 다른 일을 하시는 분들께 적용이 안될 수도 있습니다. 그러니까 너무 뭐라고 하지 마시고, 그냥 이런 곳도 있구나 하고 봐주시면 감사하겠습니다.