알고리즘 설계 기법

새로운 문제를 마주했을 때, 이를 해결할 알고리즘을 찾아야 하는 상황에서 어떻게 접근해야 할지 알아본다.

이 문제가 다른 문제와 비슷한가?

여러분이 문제를 더 일반적인 문제의 관점에서 설명할 수 있다면, 기존에 존재하는 알고리즘을 활용할 수 있다. 왜 바퀴를 다시 발명하려고 하는가?

스티븐 스키에나(Steven Skiena)의 The Algorithm Design Manual이 마음에 드는 이유 중 하나는, 시도해볼 수 있는 다양한 문제와 해결책을 카탈로그로 제공한다는 점이다. (그의 알고리즘 저장소도 참고하라.)

무식한 방법으로 시작해도 괜찮다

단순하고 무식한 방법(brute force)으로 문제를 해결하려는 접근은 실제로 사용하기에는 너무 느릴 수 있다. 하지만 이는 좋은 출발점이 된다. 무식한 방법으로 해결책을 작성하면서 문제의 본질을 이해할 수 있다.

무식한 방법으로 구현한 코드는 이후에 개선한 방법이 정확한지 검증하는 데 사용할 수 있다. 또한 작은 데이터셋만 다룬다면, 무식한 방법만으로도 충분할 수 있다. 성급한 최적화의 함정에 빠지지 않도록 주의하자!

문제 분할과 정복

"사물을 바라보는 방식을 바꾸면, 바라보는 사물이 달라진다."

막스 플랑크, 양자 이론가이자 노벨상 수상자

문제 분할과 정복은 큰 문제를 작은 조각으로 나누어 해결하는 방법이다. 전체 문제를 하나의 거대하고 복잡한 작업으로 보는 대신, 문제를 상대적으로 작고 이해하기 쉬운 부분으로 나눈다.

작은 문제를 해결하고, 그 해결책을 모아 최종적인 해결책을 얻을 때까지 진행한다. 각 단계에서 문제는 점점 작아지고, 해결책은 점점 완성되어 최종적으로 올바른 해결책을 얻게 된다.

작은 작업을 해결하고, 같은 해결책을 반복적으로(또는 종종 재귀적으로) 다른 부분에 적용하면 더 짧은 시간 안에 결과를 얻을 수 있다.