알고리즘과 문제풀이법
알고리즘 개요
알고리즘이란?
알고리즘이란 무엇일까요?
알고리즘이라고 하면 막 엄청난 수학적 공식이 떠오르고, 복잡한 문제풀이 방법이 떠오르시나요?
적어도 저는 그랬습니다.. ㅎㅎ.. 그래서 꽤나 오랫동안 알고리즘을 멀리하면서 살아왔었죠.
근데 사실 알고리즘은 따지고 보면 별거 없습니다.
알고리즘은 "문제를 해결하는 방법", 다르게 말하면 문제 푸는 법입니다.
알고리즘(영어: algorithm)은 수학과 컴퓨터과학에서 사용되는, 문제 해결 방법을 정의한 '일련의 단계적 절차'이자 어떠한 문제를 해결하기 위한 '동작들의 모임'이다. 계산을 실행하기 위한 단계적 규칙과 절차를 의미하기도 한다. 즉, 문제 풀이에 필요한 계산 절차 또는 처리 과정의 순서를 뜻한다. 프로그램명령어의 집합을 의미하기도 한다.
위키피디아에서는 위처럼 정의하긴 하는데, 걍 멋있게 표현한 것일 뿐 문제푸는 방법들을 가리키는 멋진 단어일 뿐입니다.
우리가 앞서서 빅오와 복잡도라는 멋드러진 표현으로 성능을 표현했듯이요!
한번 다음과 같은 문제를 풀어보시겠어요?
누굴 무시하는건가? 하는 생각이 드시나요? ㅎㅎ...
답은 무엇일까요? 6입니다.
그러면 이걸 어떻게 구하셨나요?
곱셈의 정의가 앞에 있는 수를 뒤에 나오는 수만큼 더하는 것이지 않나요?
그래서 2를 3번 더하니까 6이라는 결과가 나왔죠.
이처럼 문제를 푸는 방법이 알고리즘입니다.
여러분은 인지는 하지 못하였지만 곱셈이라는 알고리즘을 통해서 무의식중에 문제를 풀고 계셨던거에요!
이처럼 알고리즘은 문제푸는 방법을 지칭하는 단어 그 이상도 이하도 아닙니다. ㅎㅎ
수학적 표현이나 여러가지 요소들은 결국 이 문제 풀이 방법을 엄격하게 설명하고, 전달하기 위해 사용한 용어들일 뿐인 것이지요.
어디서 들은 이야기인데, 세상에는 자기를 뽐내는 걸 좋아하는 사람들이 많다고 합니다.
하지만 뽐낼때 좀 멋있게 뽐내고 싶고, 자기를 시기 질투하면서 깎아내리는 사람들의 입을 꽉 닫게 하고 싶잖아요?
그래서 내가 찾아낸 문제풀이 방식을 자랑할 때, 엄청 논리적으로 표현할 수 있는 수단인 수학을 써서 표현하는 것 뿐입니다.
어때요? 이렇게 놓고 보니 막연한 두려움들이 좀 사라지셨나요?
알고리즘은 왜 배우는가?
그러면 알고리즘은 왜 배울까요? 왜 중요하기에 전공 과목에서 따로 수업까지 열려가면서 집중적으로 배우게 되는 것일까요?
사실 알고리즘을 배우는 이유는 수학을 배우는 이유와 같습니다.
어떤 문제를 푸는데 보다 효율적으로, 그리고 논리적으로 접근하기 위해서 입니다!
당장 위의 곱셈 문제만 하더라도, 곱셈을 배우지 않았다면 여러분들은 매번 덧셈을 반복하면서 문제를 풀고 있어야 할 거에요!
알고리즘을 배우는 이유도 같습니다!
컴퓨터 상에서 보다 효율적으로 문제를 푸는 프로그램을 만들기 위해 알고리즘을 배운다고 할 수 있습니다.
같은 문제를 푸는데 무식하게 하드코딩해서 짜면 답을 내기까지 1시간이 걸린다고 해봅시다. (이를 naive coding
이라고 합니다.)
그런데 조금 복잡하지만 5분만에 푸는 방법이 있다고 합시다.
혼자서 5분만에 푸는 방법을 고안하기 힘드니까, 똑똑한 사람이 발견한 방법들을 우리가 낼름 배워서 써먹는 것입니다.
속된 말로 날먹이죠.
날먹하기 위해서 배운다고 보시면 됩니다.
똑똑한 사람들이 밤새워가면서 알아낸 방법을 낼름 배우는 것. 그게 곧 알고리즘을 공부하는 것이죠!
프로그래밍은 곧 어떤 문제가 주어졌을때 이를 컴퓨터를 통해 해결하는 방법을 찾는 것입니다.
이를 보다 효율적으로 진행하기 위해서, 옆에 컨닝페이퍼를 두고 문제를 푼다고 생각하시면 됩니다!
기본적인 문제 풀이 방법
알고리즘은 문제를 푸는 방법이라고 했습니다.
그리고, 우리의 스터디 목표는 코딩 테스트를 뿌수고, 실전적 코딩을 해보는 것입니다.
또한 알고리즘을 배우는 이유는 날먹하기 위해, 일종의 문제 풀이 공식이자 치트키를 익히고 써먹는 것입니다.
그럼 이제부터 제일 간단한 날먹부터 하나씩 배워봅시다.
제가 경험한 몇 가지 테크닉들이 있습니다. 이에 대해서 하나씩 설명을 해보고자 합니다.
- 문제를 읽고 분석하라 (문제를 잘 읽어라)
- 특히 입력과 출력을 명확히 하라
- 문제의 조건을 잘 따지고 히든케이스를 고려하자
- 쪼개서 생각해라
- Divide and conquer
- 의사코드를 반드시 작성하라
- 문자열 처리 -> 정규 표현식을 사용할 수 있으면 이를 활용하라
- 기본 내장 함수가 있으면 그것을 사용하라. (예: 객체, 딕셔너리, 힙, 스택 등)
뭔가 뒤죽박죽 섞여있는데, 처음 3개는 문제풀이의 태도에 대한 부분이고, 뒤의 2개는 진짜 문제풀이와 관련된 부분입니다.
차근차근 하나씩 알아봅시다.
문제를 읽고 분석하라 (문제를 잘 읽어라)
학창 시절로 돌아갑시다. 대학생 시절 말고, 초등학교, 중학교, 고등학교 때로요.
여러분들은 지금 수학 수업에 들어와있다고 상상을 해봅시다.
이러저러 원리들을 배우면서, 문제풀이를 들어갔을때 항상 선생님들이 하시는 말씀이 있죠.
문제속에 답이 있다. 그러니 문제를 잘 읽어라.
누가 그걸 몰라서 못하나? 싶은 말이고, 누가 그걸 몰라? 하는 말이지만,
잘 읽는 것 이것은 진리입니다.
정확히는 잘 읽고 잘 파악하는 것이긴 합니다.
알고보니 우리는 삶의 진리를 계속 들으면서 자라왔던 것이지요.
이는 코딩테스트나 알고리즘 문제풀이에도 적용되는 진리입니다.
다만 이렇게 이야기를 하면 진부하죠? 그래서 약간의 체크리스트를 제안해보려고 합니다.
굳이 외울필요는 없고, 그냥 이런 순서로 몸에 익히면 좋다는 의미에서 작성된거니 편하게 보시면 될 듯 해요.