알고리즘을 공부할려고 하는데,,, 어떤 방법으로 접근해야 좋은가요??

jekai의 이미지

지금 사용할줄언어는 4~5개정도, 익숙한 언어는 1~2개정도... 매년 하나의 새로운 언어는 습득하라는 말을 올해부터 옮길려고 노력하고 있습니다. 그리고 자료구조, 검색 정렬 같은 문제도 익숙합니다....
그리고 개발방법론쪽이나 개발환경쪽으로도 현재 추세에 적응할려고 하고 있는데...

여러가지 언어를 습득하는것이, 실제로 개발할때 도움이 되긴하지만 진작 중요한것은 알고리즘, 문제 해결하는 과정이 중요한듯 싶습니다.

학교다닐때, 알고리즘이란 수업을 한귀로 흘리다싶이 들었었는데, 그 선수과목이 lisp , prolog 언어였습니다.

문제 접근과정으로 알고리즘적으로 잘 해결하기 위해서 lisp 나, prolog 같은 언어를 배우면서 접근하는것이 좋은 방법일까요??

semmal의 이미지

글에서 지적하고 싶은 부분이 여러 군데 보입니다.

일단 글에서 하고 싶은 말을 짐작하자면, "문제를 해결하는데 있어서 언어를 배우는 것보다 알고리즘을 배우는 것이 더 중요하다" 라는 생각인 것 같습니다.

이렇게 생각하게 된 것은 "왜 언어를 배워야하는가?"에 대한 답을 스스로 찾지 못한 것 때문인 것 같습니다.

또, "문제를 해결한다"라는 말 또한 제대로 이해못하신 것 같습니다. 즉, 알고리즘에 대해서 잘못 이해하고 계십니다.

하나하나씩 거꾸로 짚어보겠습니다.

문제를 해결하기 위해 "차례대로 일을 하는 것 또는 그렇게 하는 방법"을 알고리즘이라 부릅니다. 하지만 이렇게 할 수 있는 "알고리즘"은 우리가 배울 수 있을 만큼 적습니다. 즉, 문제를 해결하는 수많은 방법을 따져보면 알고리즘은 극히 일부분일 뿐이라는 말입니다. 알고리즘은 어떤 문제를 쉽게 또는 효율적으로 해결할 수 있는 방법이기는 하지만 모든 문제를 해결할 수는 없습니다. 모든 문제가 알고리즘만으로 우리가 원하는 문제가 해결된다는 말은, 수학공식만 외우면 수학자가 되고, 영어 숙어만 외우면 외교관이 될 수 있다는 말입니다.

언어를 배운다는 말은 그 언어가 가지고 있는 문화와 프로그래밍 패러다임(앞으로 패러다임이라고만 하겠습니다)을 배운다는 말에 가깝습니다. 특히, lisp과 prolog를 언급한 걸로 봐서는 가르치는 분도 이 목적으로 말씀하신게 분명한 것 같습니다. 일단 각 언어의 커뮤니티가 가지고 있는 문화라는 것은 이렇게 글로도 적을 수 없는 것이니(적어봤자 논란만 일어나는 것이니) 제외를 하더라도, 패러다임의 경우에는 그나마 쉽게 배울 수 있는 부분이라 생각합니다.

패러다임이란 문제를 해결하기위해 기본적으로 사용하는, 생각하는 방향이나 방법을 어루는 말입니다. 이것은 방법론과는 또 다른데, 구현쪽에 조금 더 가깝습니다. 프로그램을 짜는데 있어서 기본 단위가 프로시저인지, 함수인지, 명제인지, 아니면 오브젝트인지에 따라서 문제 푸는 방법 자체가 달라집니다. 기본 도구가 달라지면, 같은 알고리즘의 모양도, 그 성능도 다르게 나타납니다. 기본 도구가 다르기 때문에, 프로그램을 쌓아올라가는 방식도 달라지기때문에 설계도 다릅니다. 문제를 풀어도 각 언어마다 만들어진 구조가 다르기때문에 분석도 다릅니다. 즉, 같은 문제라도 다른 패러다임으로 풀었다는 것은, 모르는 사람이 봤을 때 전혀 다른 프로그램으로 착각할 정도로 달라질 수 있습니다. 여러 언어를 쓰다 보면 어떤 문제는 저 언어에서 쉽게 풀었고, 어떤 문제는 이 언어에서 쉽게 풀린다는 걸 알게됩니다. 이건 언어의 문법이 쉽고 어렵고와는 다른 말이라는 것을 알아야합니다.

각 언어에서 쓰는 패러다임의 장점을 알게되면, 설령 피치못할 사정으로 다른 언어를 쓴다고 하더라도 이전에 썼던 언어의 장점을 가져다 쓸 수 있게 됩니다. 즉, C를 쓰면서도 object를 만들어 쓰고, Java를 쓰면서도 relation를 정의합니다. 기존의 C나 Java를 써본 사람과는 생각 자체가 다르기 때문에, 훨씬 다양한 방법으로 문제를 풀 수 있게 되는 겁니다. 같은 문제라도 다양한 방법으로 풀 수 있다는 말은, 문제를 잘 풀 수 있다는 말입니다. 검색이나 추론을 하는데 logic 언어처럼 쉽게 프로그램을 짤만한 언어는 별로 없습니다. 정확한 결과가 나와야하는 프로그램을 짜는데 functional 언어만큼 좋은 도구는 별로 없습니다. GUI를 짜는데 object-oriented 언어만큼 좋은 도구는 거의 없습니다.

아직도, 문제를 해결하는데 있어서 언어를 배우는 것보다 알고리즘을 배우는 것이 더 중요하다고 생각하십니까?
------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

김일영의 이미지

좋은 말씀입니다만, 여러 언어의 패러다임을 이해하는 것이 교본에 나오는 알고리즘을 익히는 것보다 더 중요하진 않다고 생각합니다.
사실 저도 공부 그리 잘 하지 않았고 알고리즘 공부할때 좀 귀찮아 했습니다.
그런데 그게 결국 두고 두고 많은 영향을 끼치는 것 같습니다.

소위 노가다라고 하는 일의 수준을 넘어서 좀 근원적인 솔루션이 필요하고 또 만들 기회가 있을지라도 이런 기본기들이 충실히 연마가 되어 있지 않으면 결국 실행을 못하고 맙니다.
"아 이거 sparse array 이용하면 잘 만들 것 같은데"
"아 이거 컴파일러 좀 응용하면 잘 될 것 같은데"
이런거 결국 하고 못하고의 차이는 기본기이고 그 대부분은 알고리즘입니다.

언어를 잘 익힌 분들은 그때가서 알고리즘을 생각하거나 책을 보아가며 할 수는 있습니다...
문제는 그걸 자기 기술로 쓱싹 하고 쓸 수 있느냐는 것입니다.
실제로 프로젝트에서 해결해야 할 문제가 되었을때는 자기 손에 있는 무기밖에 못 씁니다.
그제가서 새삼 공부를 해가며 만들기란 상당히 어렵습니다.

그런 실전에서 써먹을만큼 기본기를 연마하는게 나중에 두고 두고 도움이 될 것 같습니다.
저 역시 그런 점이 매우 아쉬운 사람이고요.

대부분의 알고리즘 책이 구현 코드까지 웬만큼 나와 있을테니 - 언어가 무엇이 되었든 - 그런 책을 하나 잡고 자기 손으로 하나 하나 꾹 참고 다 만들어 본다면 큰 도움이 될 것 같습니다.

특별히 이의를 제기하기 위해서라기보다는, 질문을 올리신 분께서 저같은 후회를 안 하셨으면 하는 바람에서 말씀드렸습니다.

ddoman의 이미지

알고리즘은 중요합니다.
언어는 단지 표현 도구 일 뿐입니다.
단지 각각 언어가 가지고 있는 특성상 다른 관점에서의 패러다임을 보여주는것일뿐입니다.

알고리즘은 언어와 무관합니다.

알고리즘을 배울 때, 특정언어에서의 구현 방법에 대해 많이 배우지 않습니다.

우리가 사용하고 있는 도구,기술들이 왜 그렇게 되어있는지..
그럼 효율을 갖으며 왜 그런 단점을 갖고 있는지 알려줄 수 있습니다.

적절한 언어를 배워서, 언어를 이용해서, 알고리즘을 공부해야지
언어 자체가 목적이 되면 안됩니다.

언어는 단지 표현 도구 일 뿐입니다.

jiee의 이미지

님과 같습니다. ^^

저 역시도
언어를 습득하는 것보다 문제해결능력이 더 중요하다고 생각합니다.

문제해결능력을 기르시려면 실제로 많은 문제에 도전하는 게 가장 좋다고 생각합니다.
...In fact, problem solving can be learned only by solving problems...
(아마 Problem Solving Strategies [Arthur Engel, Springer] 이책에 나온 글귀일겁니다.)

도전하고 싶은 문제들은 아래사이트에 가보시면 찾으실 수 있을겁니다.
http://www.topcoder.com/tc
http://acm.pku.edu.cn/JudgeOnline/problemlist

덧붙여, 아래 사이트에서 조언을 구하실 수 있을겁니다.
http://algospot.com

그럼, 파이팅하시길~~ : )

ps. 굳이 lisp , prolog을 배울 필요는 없을 것 같네요..

토나오게...

semmal의 이미지

제가 후배들을 가르치면서 깨달은게 있습니다.

C나 Java로 날고기는 후배도 lisp이나 prolog 책을 던져주고, 기본적인 알고리즘인 eight queen 문제를 풀어보라고 하면 못풉니다.

그렇게 되는 것은 문법을 몰라서가 아닙니다.

알고리즘을 적용하려고 해도 그 전 단계에서 막혀버리기 때문에 진도가 나가지 않는 겁니다.

일단 기본적인 패러다임에 대한 학습이 없으면, 만들어본 알고리즘이라도 그 패러다임에서는 적용하기가 쉽지않습니다.

패러다임에 상관없이 알고리즘을 적용할 수 있다고 자신하신다면, 지금이라도 lisp과 prolog로 한번 진지하게 만들어보시기를 권합니다.

예를 들어볼까요?

프로그래밍을 하시는 분이라면 미분하는 방법은 다 아시리라 생각합니다.

아래 두 링크는 각각 미분하는 프로그램을 functional 패러다임과 object-oriented 패러다임으로 각각 만든 것입니다. 알고리즘만 배워서 이렇게 하기는 쉽지 않습니다.

http://kldp.org/node/70470
http://kldp.org/node/70485

아마도 저런 것이 쓸모없는 짓이라고 생각하는 분이 계실걸로 생각합니다만, 디자인 패턴이 어떻게 나왔을 것 같습니까?

알고리즘은 분명 중요하긴 합니다만, 만능은 아닙니다.
------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

lovian의 이미지

단순히 생각해봤습니다.

보통 C를 배우다가 C++로 넘어가는 경우가 많지 않았습니까?
그 경우 C++에서 C 코드를 사용하는 사람들이 많았습니다.

버릇이겠죠.
그러나 코딩하는 버릇이라기 보다는, 생각의 버릇이라고 생각되네요.
결국 패러다임이나 다름 없다는 말이죠.
코딩 뿐 만이 아니라 알고리즘에도 기존의 패러다임이 깔려있는게 아닌가 생각해봅니다.
혹은, 기존의 알고리즘들이 해결하려는 문제 자체에 기존의 패러다임이 존재하는 것은 아닌지도

아이고, 떠올려본 생각들을 마무리짓기에는 제게 뭔가 많이 부족하네요.
하지만 왠지 의욕이 좀 생기네요 :)
-----------------
한글을 사랑합니다.

-----------------
한글을 사랑합니다.

jekai의 이미지

semmal 님 말씀 잘 들었구요, 다른님들 말씀도 잘 들었습니다... 제가 왜 이런 생각을 하게 되었냐면....
최근에 모회사에서 SEND+MORE=MONEY 라는 문제로 입사조건을 건적이 있습니다.

SEND+MORE=MONEY 는 간단한 예구요, 훨씬 복잡한 문제였는데...
저는 이문제를 손으로는 풀었는데, 막상 코드로 적용할려고 보니,, 머리에 있는 생각이 막바로 코드로 적용이 안되었습니다. ( 계속 생각해보니 되더군요;; )

그래서 이런 알고리즘측면서,,,, 자신의 생각을 얼마나 코드로 잘 이끌어낼수 있는지에서 난관에 부딧쳤습니다.

아무리 이런저런 언어를 많이 배워도,,, 그 언어의 장점을 살려 더 쉽게 개발하고, 개발방법론에서는 여러언어의 장점을 알 수 있으니 도움은 되더군요...

그치만, 저런 문제해결방향에서, 생각-->코드 로 바꿔가는것을 이제 훈련할려고 이런 질문을 올렸던것입니다. ;;;;;;

그동안 웹써핑하면서 이곳저곳 돌아다녀봤는데, 결국 답은 "생각" 이더군요,,, 평소에 아무런 생각없이 개발하거나,,, 어려운 문제를 계속 풀지 않는한
저런 문제 해결능력은 점점 굳어지는것 같습니다 ( 지금처럼 ;;; )

더 좋은 의견있으시면 답변 부탁드릴꼐요 ㅎㅎ

semmal의 이미지

일단 알고리즘은 신경쓰지 마시고, 문제를 많이 풀어보도록 해보세요.

말씀하신 대로 "생각을 코드로 잘 이끌어내는 것"을 그저 프로그래밍이라 부릅니다. 알고리즘이 아니구요.

저도 풀어본바 있는, 언급하신 문제는 굳이 알고리즘을 몰라도 해결할 수 있어야합니다.

이건 알고리즘과는 다른 겁니다. 휴우~.

다시 말씀드리지만, 수많은 문제중에 "일부"의 문제에 대해서는 알고리즘으로 쉽게 푸는 방법을 배울 수 있습니다.

하지만, 프로그래밍을 제대로 하는 사람에게, 알고리즘은 단지 코드의 성능에만 영향을 줄 뿐입니다.

즉, 프로그래머는 어떤 방법으로든 문제는 해결할 수 있지만, 효율적인 생각이나 구현을 하기위해 쓰는 것이 알고리즘이라 이해하시면 됩니다.

알고리즘을 배운다고 문제 해결 능력이 올라가는게 아닙니다.

어떤 언어를 쓰든 어쨌든 꾸준히 문제를 풀어보세요.

Practice of Programming과 같은 책이나 인터넷에서 Ninety-Nine Problems와 같은 문제들을 찾아보는 것이 도움이 될 것 같습니다.

ACM-ICPC나 그와 비슷한 곳에서 제출한 문제를 풀어보는 것도 도움이 될 겁니다.

어쨌든 뭘 하든 문제를 해결하는 것에만 집중하세요. 배우는 입장에서는 성능이나 효율은 그 다음에 따져도 충분합니다.
------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

jiee의 이미지

'알고리즘'이란 용어를 좀 좁게 보신 건 아닌가 하네요,
'알고리즘'이란 용어 자체의 의미는
"유한한 단계를 통해 문제를 해결하기 위한 절차나 방법이다. 주로 컴퓨터용어로 쓰이며, 컴퓨터가 어떤 일을 수행하기 위한 단계적 방법을 말한다. -네이버 백과사전-"입니다. (말씀하신 의미는 특정 알고리즘을 의미하시는 것 같네요, 다익스트라 최단거리 알고리즘과 같은?)

그래서, 저는 문제해결을 위해선 알고리즘을 구상하는 시간이 꼭 필요하다고 봅니다.
자판부터 바로 치는 게 아니라,
문제를 어떻게 해결할지를 결정하는 일련의 과정인 알고리즘을 구상하는 시간을 갖는 것이죠.

덧붙여, 문제해결능력 향상을 위해 특정 알고리즘을 배울 필요가 없다는 말씀에도 제 생각은 좀 다르네요,
대부분의 대학에선 알고리즘을 배울 때, 옛 컴퓨터과학자분들이 고안한 특정 알고리즘들을 배웁니다.
이것이 의미있는 이유는 그런 특정 알고리즘들을 배우는 과정에서 그 과학자분들의 사고를 따라가보며
새로운 문제를 해결하는 롤모델을 삼는 것이죠.

끝으로, 이런 제목의 책이 있죠.
Algorithms + Data Structures = Programs
요새는 다양한 개발방법론이 나오지만, 근본은 변하지 않는다고 생각합니다.

토나오게...

semmal의 이미지

제 말이 자칫 알고리즘이 필요없다라고 주장하는 것일 수도 있게 보이네요. 제 말은 그런 말은 아니구요.

jiee님이 말씀하신 알고리즘과 우리가 배운다고 말하는 알고리즘은 다르지 않을까요?

제가 GUI를 만들면서 어떤 버튼(View)과 어떤 함수(Model)를 연결해도 알고리즘이라 할 수는 있습니다. (더 복잡하게는 생각하지 맙시다)

그래도, 이런 셀수없을만치 많은 알고리즘을 "차근차근 배워서" 써먹는 건 아닙니다.

메뉴얼이나 튜토리얼만 보고도 어느정도 본질을 꿰뚫어서 당연한 것 처럼 어느순간 자연스럽게 쓰게 되는 것이지, 이런 것을 누군가에게 물어보고, 굳이 책을 보고 공부를 해야하는 사람이라면 "프로그래밍에 익숙하지 않다"라고 말해도 틀린 말이 아니라 생각합니다.

우리가 학교에서 과목으로 배워야 하는 알고리즘은 상황에 맞게 "알고리즘을 적용하기 쉽게" 만들고, 더 "성능좋은 코드를 작성"하기 위해 필요합니다.

설령 그런 알고리즘을 배우지 못해다고 하더라도, 스스로 그 문제를 해결하는 방법을 생각할 수 있어야 한다는 겁니다.

이렇게 스스로 해결할 수 있으면 그것을 jiee님이 말씀하신 "알고리즘"으로 말할 수도 있겠지요.

알고리즘을 배워봤자 기계적으로 배웠기때문에, 종이에 적으라고 하면 신나게 잘 적는 사람들이, 정작 "생각을 코드로 옮기는 일"을 어디서부터 시작해야할지 막막해하는 사람을 많이 봤습니다.

말씀하신 대로 알고리즘은 생각의 방향을 알려줄 수 있습니다. 이건 분명 필요한 일이구요.

하지만 이것은 "생각을 코드로 옮기는 일"을 제대로 할 수 있게 된 이후에 필요한 것입니다.

문제를 많이 풀어보고, 그 정답을 알아봅니다. 그 정답은 여러가지일 수 있지만, 어쨌든 문제를 풀고나서 왜 그런 답이 나왔는지는 확실하게 머리속에 들어가 있어야 합니다.

이것이 쌓이다보면 어느 순간 "생각이 코드로 옮기는 일"이 자연스럽게 되고, 나중에 알고리즘을 공부하면서도 복잡한 알고리즘이나 공식을 보더라도 머리가 혼란스러워지는 일은 별로 없을 것이라 생각합니다.
------------------------------
How many legs does a dog have?

------------------------------
How many legs does a dog have?

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.