출처 : http://cafe.naver.com/unityhub
프로그래밍을 처음부터 어떻게 공부해야 하는지 난감하기만하신 분들에게
조금이나마 도움이 될까해서 저의 경험들을 떠올리면서 몇 자 적어봅니다.
국민학교를 다닐 때 베이직을 수박겉핥기 수준으로 배우고, 컴퓨터는 오로지
오락기쯤으로 여겼던 제가 컴퓨터 학원을 다녔던 이유도 게임을 하기 위해서 였습니다.
그렇게 컴퓨터를 뜯었다 고쳤다 컴퓨터를 가지고 노는 데에만 미쳐있던 제가
17살 때 부터 본격적으로 C언어를 공부하기 시작한 이유는 조금은 황당합니다.
그날도 마찬가지로 컴퓨터를 가지고 놀다 어디선가 복사해 온 테트리스를 실행시켰는데
"만든이> 포항공대 김개똥!!" 이라고 적혀있는 겁니다.
저는 그런 대단한 프로그램은 특별한 기업에서만 만들어 내는 줄 알았지 사람?이
만들었다는건 생각도 못했습니다.
게임을 만드는 회사도 결국 사람이 일하는것이 분명했을 터인데 철없고, 무식했던 저에게
대학생이 게임을 만들었다는것이 엄청난 충격이 아닐 수 없었습니다.
그 때 친누나가 대학을 다니고 있었기 때문에 그런 누나(컴맹)와 친구?같은 사람이 이렇게 깔끔하고
멋진 테트리스를 만들었다는 말이야?하고 머리를 큰 헤머로 맞은듯 나도 맨날 납땜질만 할게 아니라
소프트웨어를 만들어야 겠구나 하고 마음을 먹었습니다.
그러고는 자취방 주변에 있던 컴퓨터 학원을 다짜고짜 찾아갔습니다.
학원을 두리번 거리던 저에게 수업을 하시던 선생님들이 나오셔서 무슨 용무냐고 물으시길래
제 상황을 설명드리고, "어떤 언어가 가장 좋은지? 개발툴이 있으면 복사해주시고, 책도 빌려주세요!"라고
다소 황당하게 말했습니다.
그 학원 선생님들은 참으로 고맙게도 "그럼 학원을 다니세요"라 하지는 않고, C언어가 지금은 가장 좋은것
같다. 그리고 Turbo-C 컴파일러와 "C언어 500예제"라는 책을 누군지도 모르는 저에게 빌려주셨습니다.
[Turbo-C 컴파일러]
![]()
집에 가서 위에 보이는 터보씨를 실행해보니 오류만 뜨고, 아무런 동작을 하지 않길래 또 찾아갔더니
이번에는 그 여 선생님의 남편이 오셔서 문제를 해결해 주셨습니다.
(그 여 선생님은 신혼이셨는지 다른 회사에 근무하던 남편이 땀을 뻘뻘 흘리면서 학원에 도착했을 때
그 남편을 바라보던 눈빛이 아직도 기억납니다. 뭐라고 말하진 않아도 사랑이 철철 넘쳐 흐른다고 해야하나요. ^^
지금은 40~50정도 되셨을 그분들이 혹시나 이글을 보신다면 정말 다시 만나뵙고 싶습니다. ㅠㅠ
부산 동래구 온천장 부근의 금정 컴퓨터 학원이었던가? 네티즌 수사대님들 제발 찾아주셔요.)
어쨌거나 문제는 해결되었고, 집으로 돌아가 "Hello world" 예제를 실행했더니
내 눈 앞에 "Hello world.exe"라는 파일이 만들어 지고야 말았습니다.
그 날 저는 잠을 잘 수 없을 정도로 큰 기쁨을 느꼈고, 빌려주신 프로그래밍 500예제는 제가 만져 본 책 중에서는
가장 두꺼웠는데도 일주일만에 모두 다 읽었습니다.
처음에는 이해고 뭐고 없었습니다. 그냥 책을 읽고, 예제를 그대로 따라 타이핑 해보고, 실행되는 모습에 감탄하고...
지금 생각해보면 정말 별것 아닌 그런것이 저에게는 판타지 소설책을 읽는 기분이었습니다.
이 처럼 프로그래밍에 재미만 붙일 수 있다면 프로그래머가 되는것은 시간문제일 뿐입니다.
지금 부터는 제가 프로그래밍을 처음 하면서 고민했던것에 대한 효과적인 학습방법들을 설명하도록 하겠습니다.
첫째. 처음 이해가 안될때는 무조건 보고해라 (Copy and paste)
-------------------------------------------------------------------------------------------------
코딩을 하면서 책을 보거나 인터넷을 뒤져보는것을 초보라 생각하는 사람들이 있습니다.
절대 그렇지 않습니다. 제가 배울때는 딱히 적어둘곳이 없어서 수첩에다 일일이 적었습니다.
그 수첩을 재산처럼 가지고 다니면서 단순하게는 for문 사용법 부터 해서 그래픽 모드로 전환하는
방법까지 모두 적어 두었다가 필요할때가 되면 그 부분을 찾아서 그대로 응용했습니다.
요즘은 인터넷 세상이니 네이버의 개인 블로그에 참조할만한 예제나 문법들을 계속 적어두고 참조하세요.
(클래스나 함수 이름을 모두 기억해야 한다 생각하지 마세요. 프로그래밍은 수능이 아니니 절대로 컨닝을 하세요.)
둘째. 남들이 만든 프로그램이나 소스코드를 분석해라 (Bench Marking)
-------------------------------------------------------------------------------------------------
이론적인 공부만 하고도 프로그램을 뚝딱 만들 수 있다면, 엄청난 직관력을 가진 분이 아닌가 싶습니다.
대부분은 그러지 못하니 작은 프로그램들을 조금씩 분석하세요. 분석이 싫다면 남이 만든 프로그램들을
감상부터 하세요. (책을 사면 예제 위주로 만들어진 책의 소스코드나 인터넷 상에서 돌아다니는게 많습니다.)
그러면서 이런 프로그램이 있구나! 저런 프로그램이 있구나! 이렇게 구현했구나! 저렇게 구현했구나!
아니면 ~ 분석할려니 너무 머리가 아프게 복잡하게 만들어 졌구나! 정말 이해하기 편하게 만들어 졌구나!
하면서 많은것들을 느끼고, 남의것을 분석하는것이 쉽지는 않구나 라는것도 느낄겁니다.
이렇게 남의것을 보기도하고, 조금씩 자신의것을 구현하다 보면 어느 새 프로그래밍이라는게 편하게 다가 올 시기가 옵니다.
(처음 낯선곳에 갔을 때는 어색하다가 한달 두달 지나면 고향보다 더 익숙한 곳으로 변하는것 처럼 만드세요)
셋째. 프로그래밍 용어와 기능을 이해해라 (Technical Understanding)
-------------------------------------------------------------------------------------------------
대부분의 프로그래밍은 어떤 언어를 막론하고, 필요로하는 기술들은 다들 비슷비슷 합니다.
다만, 프로그래밍의 역사가 길어진 요즘에는 그 용어와 기술들이 엄청나게 많습니다.
그렇다고 하더라도 그런 프로그래밍 세계에서의 용어들을 마이동풍과 같이 흘려보내기만 한다면
고급 프로그래머가 되는데에는 시간이 더 많이 걸릴겁니다.
예를들어서 서버, 클라이언트, 네트워킹, 데이터베이스, 멀티스레드와 같은 큰 개념에서 부터
게임 그래픽 관련 용어나 리스트, 해쉬테이블, 트리와 같이 상세한 개념까지 처음듣는용어가 있다면
적어도 수박 겉핥기 정도는 해두셔야 합니다.
물리학자들이 어떤 이론을 설명할 때 수학식으로 설명하듯 수학에 대한 깊은 이해가 없다면
아무런 의사전달이 되지 않겠지요. 프로그래머들도 대부분의 이야기들이 기술적인 용어들이 많기 때문에
관련 용어들을 이해하지 못한다면 난감합니다.
(프로그래밍이라는 것이 단순한 개념 하나만으로 만들 수 있는것이 아니기 때문에 이 과정이 가장 오래 걸립니다)
넷째. 남들이 하는 이야기에 귀를 기울여라 (Communication)
-------------------------------------------------------------------------------------------------
위의 세번째에 익숙해 졌다면 이제부터는 프로그래머들의 이야기가 귀에 들리기 시작할겁니다.
책 중에는 당장 코딩에 도움이 되는 예제나 메뉴얼 형식의 책도 있지만, 특정분야나 개발툴에 대한 전반적인
이야기를 들려주는 책들이 있지요.
그런것 처럼 커뮤니티 사이트에서 많은 사람들이 하는 이야기와 문제점에 대해서
당장 필요하지는 않더라도 관심을 가질 필요가 있습니다.
제 아무리 뛰어난 프로그래머라도 혼자서 모든 상황을 겪어보기는 힘들것이고,
그런 문제에 봉착했을 때 ~ 아 옛날에 그런 이야기를 들었었는데, 문제가 거기에 있는걸까? 하고
문제해결의 실마리를 찾을수도 있습니다.
프로그래밍은 혼자 산속에 들어가 10년을 수양을 한다해서 고수가 될 수 있는것이 아니고,
많은 사람들과 소통하고 함께 이루어 가야한다는것을 알아야 합니다.
-------------------------------------------------------------------------------------------------
너무 조바심 내지말고, 포기하지 마세요.
'잡다한것들전부 > 기타' 카테고리의 다른 글
| [펌]컴퓨터 게임 제작 : 길찾기 알고리즘 구현 (0) | 2014.01.13 |
|---|---|
| [펌]왕초보 게임 만들기 - 길찾기 알고리즘 A*(A star, A스타) (0) | 2014.01.13 |
| [블로그] 더블 클릭시 맨 하단으로 이동하는 코드입니다. (0) | 2014.01.13 |
| [펌][블로그] 글자 클릭시 해당 지점으로 이동하는 방법 (0) | 2014.01.13 |
| [잡담] 어둠속을 헤매는 초보분들을 위해 ~ (0) | 2014.01.12 |
| [블로그] 블로그에 코딩 색 입히는 방법. (0) | 2014.01.10 |
c# 자바 등을 하다보니까 c++ 이랑 헷갈리는개념.. abstract 란 키워드가 없음
추상 클래스 (C++)
// deriv_AbstractClasses.cpp
// compile with: /LD
class Account {
public:
Account( double d ); // Constructor.
virtual double GetBalance(); // Obtain balance.
virtual void PrintBalance() = 0; // Pure virtual function.
private:
double _balance;
};
이 선언과 이전 선언은 순수 지정자 = 0 선언없이 PrintBalance가 선언된 점이 다릅니다.
'잡다한것들전부 > C, C++, C#' 카테고리의 다른 글
| c++에서 bool 형 값 true false 실수할 수 있는 부분 (0) | 2014.01.13 |
|---|---|
| 동기화 비동기화 동기식 비동기식 이란? (0) | 2014.01.13 |
| 추상 클래스 (C++) (0) | 2014.01.10 |
| Duff's Device (0) | 2014.01.10 |
| c++ 11 이란?? (0) | 2014.01.09 |
| strncpy 로 메모리 복사 (0) | 2014.01.07 |
저자 : 최흥배
이전기사 :
- About STL : C++ STL 프로그래밍(1)
- About STL : C++ STL 프로그래밍(2-1)
- About STL : C++ STL 프로그래밍(2-2)
- About STL : C++ STL 프로그래밍(3)
- About STL : C++ STL 프로그래밍(4)
- About STL : C++ STL 프로그래밍(5-1)
- About STL : C++ STL 프로그래밍(5-2)
- About STL : C++ STL 프로그래밍(6)
- About STL : C++ STL 프로그래밍(7)
- About STL : C++ STL 프로그래밍(8)
- About STL : C++ STL 프로그래밍(9)
이번 회는 이전 회에 설명하지 못한 '정렬 관련 알고리즘' 과 '범용 수치 알고리즘'의 주요 알고리즘의 특징과 사용 방법에 대해서 설명하겠습니다.
10.1. 정렬 관련 알고리즘
10.1.1 sort
sort는 컨테이너에 있는 데이터들을 내림차순 또는 오름차순으로 정렬 할 때 가장 자주 사용하는 알고리즘입니다. 컨테이너에 저장하는 데이터의 자료 형이 기본형이라면 STL에 있는 greate나 less 비교 조건자를 사용합니다(STL의 string의 정렬에도 사용할 수 있습니다. 다만 이 때는 알파벳 순서로 정렬합니다). 기본형이 아닌 경우에는 직접 비교 조건자를 만들어서 사용해야 합니다.
sort의 원형
template<class RandomAccessIterator> void sort( RandomAccessIterator _First, RandomAccessIterator _Last );첫 번째와 두 번째 파라미터는 정렬하려는 구간의 시작과 마지막을 가리키는 반복자입니다. 비교 조건자를 필요로 하지 않고 기본형을 저장한 컨테이너를 오름차순으로 정렬합니다.
template<class RandomAccessIterator, class Pr> void sort( RandomAccessIterator _First, RandomAccessIterator _Last, BinaryPredicate _Comp );첫 번째와 두 번째 파라미터는 정렬하려는 구간의 시작과 마지막을 가리키는 반복자입니다. 세 번째 파라미터는 정렬 방법을 기술한 비교 조건자입니다.
sort 알고리즘의 원형을 보면 알 수 있듯이 램덤 접근 반복자를 지원하는 컨테이너만 sort 알고리즘을 사용할 수 있습니다.
sort 사용 방법
vector<int> vec1; ….. // 오름차순 정렬 sort( vec1.begin(), vec1.end() ); // 내림차순 정렬 Sort( vec1.begin(), vec1.end(), greater<int>() );< 리스트 1. less와 greater 비교 조건자를 사용한 sort >
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
vector<int> vec1(10);
vector<int> vec2(10);
vector<int> vec3(10);
vector <int>::iterator Iter1;
generate( vec1.begin(), vec1.end(), rand );
generate( vec2.begin(), vec2.end(), rand );
generate( vec3.begin(), vec3.end(), rand );
// 오름차순 정렬
cout << "vec1 정렬 하기 전" << endl;
for( Iter1 = vec1.begin(); Iter1 != vec1.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
sort( vec1.begin(), vec1.end() );
cout << "vec1 오름차순 정렬" << endl;
for( Iter1 = vec1.begin(); Iter1 != vec1.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
cout << endl;
// 내림차순 정렬
cout << "vec2 정렬 하기 전" << endl;
for( Iter1 = vec2.begin(); Iter1 != vec2.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
sort( vec2.begin(), vec2.end(), greater<int>() );
cout << "vec2 내림차순 정렬" << endl;
for( Iter1 = vec2.begin(); Iter1 != vec2.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
cout << endl;
// 일부만 내림차순 정렬
cout << "vec3 정렬 하기 전" << endl;
for( Iter1 = vec3.begin(); Iter1 != vec3.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
sort( vec3.begin() + 5, vec3.end(), greater<int>() );
cout << "vec3 일부만 내림차순 정렬" << endl;
for( Iter1 = vec3.begin(); Iter1 != vec3.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
return 0;
}
< 결과 >
<리스트 1>은 기본 형 데이터를 정렬하는 예제로 이번에는 유저 정의 형 데이터를 정렬하는 예제를 보여 드리겠습니다.
< 리스트 2. USER 구조체의 Money를 기준으로 정렬 >
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
struct USER
{
int UID;
int Level;
int Money;
};
struct USER_MONEY_COMP
{
bool operator()(onst USER& user1, const USER& user2)
{
return user1.Money > user2.Money;
}
};
int main()
{
USER User1; User1.UID = 1; User1.Money = 2000;
USER User2; User2.UID = 2; User2.Money = 2050;
USER User3; User3.UID = 3; User3.Money = 2200;
USER User4; User4.UID = 4; User4.Money = 1000;
USER User5; User5.UID = 5; User5.Money = 2030;
vector<USER> Users;
Users.push_back( User1 ); Users.push_back( User2 );
Users.push_back( User3 ); Users.push_back( User4 );
Users.push_back( User5 );
vector <USER>::iterator Iter1;
cout << "돈을 기준으로 정렬 하기 전" << endl;
for( Iter1 = Users.begin(); Iter1 != Users.end(); ++Iter1 ) {
cout << Iter1->UID << " : " << Iter1->Money << ", ";
}
cout << endl << endl;
sort( Users.begin(), Users.end(), USER_MONEY_COMP() );
cout << "돈을 기준으로 내림차순으로 정렬" << endl;
for( Iter1 = Users.begin(); Iter1 != Users.end(); ++Iter1 ) {
cout << Iter1->UID << " : " << Iter1->Money << ", ";
}
cout << endl << endl;
return 0;
}
< 결과 >
10.1.2. binary_search
이미 정렬 되어 있는 것 중에서 특정 데이터가 지정한 구간에 있는지 조사하는 알고리즘입니다. 이것도 sort와 같이 비교 조건자가 필요 없는 버전과 필요한 버전 두 개가 있습니다(단 sort와 다르게 랜덤 접근 반복자가 없는 컨테이너도 사용할 수 있습니다).
binary_search 원형
template<class ForwardIterator, class Type>
bool binary_search( ForwardIterator _First, ForwardIterator _Last, const Type& _Val );
template<class ForwardIterator, class Type, class BinaryPredicate>
bool binary_search( ForwardIterator _First, ForwardIterator _Last, const Type& _Val,
BinaryPredicate _Comp );
binary_search 사용 방법vector<int> vec1; ….. sort( vec1.beign(), vec1.end() ); …... bool bFind = binary_search( vec1.begin(), vec1.end(), 10 );binary_search는 정렬한 이후에 사용해야 한다고 앞서 이야기 했습니다. 만약 정렬하지 않고 사용하면 어떻게 될까요?
< 리스트 3. 정렬하지 않고 binary_search 사용 >
int main()
{
vector<int> vec1;
vec1.push_back(10); vec1.push_back(20); vec1.push_back(15);
vec1.push_back(7); vec1.push_back(100); vec1.push_back(40);
vec1.push_back(11); vec1.push_back(60); vec1.push_back(140);
bool bFind = binary_search( vec1.begin(), vec1.begin() + 5, 15 );
if( false == bFind ) {
cout << "15를 찾지 못했습니다." << endl;
} else {
cout << "15를 찾았습니다." << endl;
}
return 0;
}
디버그 모드로 빌드 후 실행 하면 아래와 같은 에러 창이 나옵니다.
에러 내용은 시퀀스가 정렬되지 않았다고 나옵니다. 릴리즈 모드 빌드 후 실행하면 위와 같은 에러는 나오지 않지만 결과는 false가 나옵니다.
binary_search를 사용할 때는 꼭 먼저 정렬해야 한다는 것을 잊지 말기를 바랍니다.
< 리스트 4. 정렬 후 binary_search 사용 >
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
vector<int> vec1;
vec1.push_back(10); vec1.push_back(20); vec1.push_back(15);
vec1.push_back(7); vec1.push_back(100); vec1.push_back(40);
vec1.push_back(11); vec1.push_back(60); vec1.push_back(140);
sort( vec1.begin(), vec1.end() );
bool bFind = binary_search( vec1.begin(), vec1.begin() + 5, 15 );
if( false == bFind ) {
cout << "15를 찾지 못했습니다." << endl;
} else {
cout << "15를 찾았습니다." << endl;
}
return 0;
}
< 결과 >
비교 조건자를 사용하는 경우는 위의 <리스트 2> 코드를 예를들면 <리스트 2>에서 사용했던 USER_MONEY_COMP 조건자를 사용합니다.
< 리스트 4. 리스트 2의 Users를 binary_search에 사용 >
……. sort( Users.begin(), Users.end(), USER_MONY_COMP() ); bool bFind = binary_search( Users.begin(), Users.begin() + 3, User5, USER_MONY_COMP() ); …….10.1.3 merge
두 개의 정렬된 구간을 합칠 때 사용하는 것으로 두 구간과 겹치지 않은 곳에 합친 결과를 넣어야 합니다. 주의해야 할 점은 합치기 전에 이미 정렬이 되어 있어야 하며 합친 결과를 넣는 것은 합치는 것들과 겹치면 안되며, 또한 합친 결과를 넣을 수 있는 공간을 확보하고 있어야 합니다.
merge의 원형
template<class InputIterator1, class InputIterator2, class OutputIterator>
OutputIterator merge( InputIterator1 _First1, InputIterator1 _Last1,
InputIterator2 _First2, InputIterator2 _Last2, OutputIterator _Result
);
template<class InputIterator1, class InputIterator2, class OutputIterator, class BinaryPredicate>
OutputIterator merge( InputIterator1 _First1, InputIterator1 _Last1,
InputIterator2 _First2, InputIterator2 _Last2, OutputIterator _Result, BinaryPredicate _Comp );
merge 사용 방법vector<int> vec1, vec2, vec3; ….. merge( vec1.begin(), vec1.end(), vec2.begin(), vec2.end(), vec3.begin() );아래의 <리스트 5>는 vec1과 vec2를 합쳐서 vec3에 넣는 것으로 vec1과 vec2는 이미 정렬되어 있고 vec3는 이 vec1과 vec2의 크기만큼의 공간을 미리 확보해 놓고 있습니다.
< 리스트 5. 두 개의 vector의 merge >
#include <vector>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
int main()
{
vector <int>::iterator Iter1;
vector<int> vec1,vec2,vec3(12);
for( int i = 0; i < 6; ++i )
vec1.push_back( i );
for( int i = 4; i < 10; ++i )
vec2.push_back( i );
cout << "vec1에 있는 값" << endl;
for( Iter1 = vec1.begin(); Iter1 != vec1.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
cout << "vec2에 있는 값" << endl;
for( Iter1 = vec2.begin(); Iter1 != vec2.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
merge( vec1.begin(), vec1.end(),
vec2.begin(), vec2.end(),
vec3.begin() );
cout << "vec1과 vec2를 merge한 vec3에 있는 값" << endl;
for( Iter1 = vec3.begin(); Iter1 != vec3.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
return 0;
}
< 결과 >
정렬 관련 알고리즘은 위에 소개한 세 개 이외에도 더 있지만 지면 관계상 보통 자주 사용하는 sort, binary_search, merge 세 개를 소개하는 것으로 마칩니다. 제가 소개하지 않은 정렬 관련 알고리즘을 더 공부하고 싶은 분들은 MSDN이나 C++ 책을 통해서 공부하시기를 바랍니다.
10.2. 범용 수치 알고리즘
10.2.1 accumulate
지정한 구간에 속한 값들을 모든 더한 값을 계산합니다. 기본적으로 더하기 연산만 하지만 조건자를 사용하면 더하기 이외의 연산도 할 수 있습니다. accumulate를 사용하기 위해서는 앞서 소개한 알고리즘과 다르게 <numeric> 헤더 파일을 포함해야 합니다.
accumulate의 원형
template<class InputIterator, class Type> Type accumulate( InputIterator _First, InputIterator _Last, Type _Val );첫 번째와 두 번째 파라미터는 구간이며, 세 번째 파라미터는 구간에 있는 값에 더할 값입니다.
template<class InputIterator, class Type, class BinaryOperation> Type accumulate( InputIterator _First, InputIterator _Last, Type _Val, BinaryOperation _Binary_op );네 번째 파라미터는 조건자로 조건자를 사용하여 기본 자료 형 이외의 데이터를 더할 수 있고, 더하기 연산이 아닌 다른 연산을 할 수도 있습니다.
accumulate 사용 방법
vector<int> vec1; ….. // vec1에 있는 값들만 더 한다. int Result = accmulate( vec1.begin(), vec1.end(), 0, );아래의 <리스트 6>은 int를 저장하는 vector를 대상으로 accmurate를 사용하는 가장 일반적인 예입니다.
< 리스트 6. vector에 있는 값들을 계산 >
#include <vector>
#include <iostream>
#include <numeric>
using namespace std;
int main()
{
vector <int>::iterator Iter1;
vector<int> vec1;
for( int i = 1; i < 5; ++i )
vec1.push_back( i );
// vec1에 있는 값
for( Iter1 = vec1.begin(); Iter1 != vec1.end(); ++Iter1 ) {
cout << *Iter1 << ", ";
}
cout << endl;
// vec1에 있는 값들을 더한다.
int Result1 = accumulate( vec1.begin(), vec1.end(), 0 );
// vec1에 있는 값들을 더한 후 10을 더 한다.
int Result2 = accumulate( vec1.begin(), vec1.end(), 10 );
cout << Result1 << ", " << Result2 << endl;
}
< 결과 >
이번에는 조건자를 사용하여 유저 정의형을 저장한 vector를 accmulate에서 사용해 보겠습니다. 이번에도 더하기 연산만을 했지만 조건자를 사용하면 곱하기 연산 등도 할 수 있습니다.
< 리스트 7. 조건자를 사용한 accumulate >
#include <vector>
#include <iostream>
#include <numeric>
using namespace std;
struct USER
{
int UID;
int Level;
int Money;
};
struct USER_MONY_ADD
{
USER operator()(const USER& user1, const USER& user2)
{
USER User;
User.Money = user1.Money + user2.Money;
return User;
}
};
int main()
{
USER User1; User1.UID = 1; User1.Money = 2000;
USER User2; User2.UID = 2; User2.Money = 2050;
USER User3; User3.UID = 3; User3.Money = 2200;
USER User4; User4.UID = 4; User4.Money = 1000;
USER User5; User5.UID = 5; User5.Money = 2030;
vector<USER> Users;
Users.push_back( User1 ); Users.push_back( User2 );
Users.push_back( User3 ); Users.push_back( User4 );
Users.push_back( User5 );
vector <USER>::iterator Iter1;
for( Iter1 = Users.begin(); Iter1 != Users.end(); ++Iter1 ) {
cout << Iter1->UID << " : " << Iter1->Money << ", ";
}
cout << endl << endl;
// Users에 있는 Money 값만 더하기 위해 Money가 0인 InitUser를 세 번째 파라미터에
// 조건자를 네 번째 파라미터로 넘겼습니다.
USER InitUser; InitUser.Money = 0;
USER Result = accumulate( Users.begin(), Users.end(), InitUser, USER_MONY_ADD() );
cout << Result.Money << endl;
}
< 결과 >
10.2.2 inner_product
두 입력 시퀀스의 내적을 계산하는 알고리즘으로 기본적으로는 +와 *을 사용합니다. 두 입력 시퀀스의 값은 위치의 값을 서로 곱한 값을 모두 더 한 것이 최종 계산 값이 됩니다. 주의 해야 할 것은 두 입력 시퀀스의 구간 중 두 번째 시퀀스는 첫 번째 시퀀스 구간 보다 크거나 같아야 합니다. 즉 첫 번째 시퀀스 구간의 데이터는 5개가 있는데 두 번째 시퀀스에 있는 데이터가 5개 보다 작으면 안됩니다.
inner_product의 원형
template<class InputIterator1, class InputIterator2, class Type>
Type inner_product( InputIterator1 _First1, InputIterator1 _Last1, InputIterator2 _First2,
Type _Val );
조건자를 사용하는 버전으로 조건자를 사용하면 유저 정의형을 사용할 수 있는 내적 연산 방법을 바꿀 수 있습니다.template<class InputIterator1, class InputIterator2, class Type,
class BinaryOperation1, class BinaryOperation2>
Type inner_product( InputIterator1 _First1, InputIterator1 _Last1, InputIterator2 _First2,
Type _Val, BinaryOperation1 _Binary_op1, BinaryOperation2 _Binary_op2 );
아래의 <리스트 8>은 조건자를 사용하지 않는 inner_product를 사용하는 것으로 vec1과 vec2의 내적을 계산합니다. < 리스트 8. inner_product를 사용하여 내적 계산 >
#include <vector>
#include <iostream>
#include <numeric>
using namespace std;
int main()
{
vector<int> vec1;
for( int i = 1; i < 4; ++i )
vec1.push_back(i);
vector<int> vec2;
for( int i = 1; i < 4; ++i )
vec2.push_back(i);
int Result = inner_product( vec1.begin(), vec1.end(), vec2.begin(), 0 );
cout << Result << endl;
return 0;
}
< 결과 >
<리스트 8>의 vec1과 vec2에는 각각 1, 2, 3 의 값이 들어가 있습니다. 이것을 네 번째 파라미터의 추가 값을 0을 넘긴 inner_droduct로 계산하면
14 = 0 + (1 * 1) + (2 * 2) + (3 * 3);
가 됩니다.
<리스트 8>의 코드를 보기 전에는 어떻게 계산 되는지 잘 이해가 되지 않는 분들은 <리스트 8> 코드를 보면 inner_product가 어떻게 계산 되는지 쉽게 이해할 수 있을 것입니다.
inner_product도 다른 알고리즘처럼 조건자를 사용할 수 있습니다. 제가 앞서 다른 알고리즘에서 조건자를 사용한 예를 보여 드렸으니 inner_product에서 조건자를 사용하는 방법은 숙제로 남겨 놓겠습니다.^^
범용 수치 알고리즘에는 위에 설명한 accmulate와 inner_product 이외에도 더 있지만 다른 것들은 보통 사용 빈도가 높지 않고 그것들을 다 소개하기에는 많은 지면이 필요로 하므로 이것으로 끝내겠습니다.^^;
범용 수치 알고리즘을 끝으로 STL의 알고리즘을 설명하는 것을 마치겠습니다. 이전 회와 이번에 걸쳐서 소개한 알고리즘은 STL에 있는 알고리즘 중 사용 빈도가 높은 알고리즘들로 이 것 이외에도 많은 알고리즘이 있으니 제가 설명한 알고리즘을 공부한 후에는 제가 설명하지 않은 알고리즘들도 공부하시기를 바랍니다.
지금까지 제가 설명한 글들을 보시면 STL은 사용할 때 일관성이 높다라는 것을 알 수 있을 것입니다. 높은 일관성 덕분에 하나를 알면 그 다음은 더 쉽게 알 수 있습니다.
C++의 STL은 결코 사용하기 어려운 것이 아닙니다. C++을 알고 있다면 아주 쉽게 공부할 수 있으며 STL을 사용함으로 더 쉽고 견고하게 프로그래밍할 수 있습니다. 그러나 STL의 컨테이너나 알고리즘에 대해서 잘 모르면서 다른 사람들이 사용한 코드를 보고 그냥 사용하면 STL이 독이 될 수도 있음을 조심해야 합니다.
저는 몇 달 전부터 C++0x을 공부하고 있습니다. C++0x는 현재 개발중인 새로운 C++ 표준입니다. C++0x에는 지금의 C++을 더 강력하고 쉽게 사용할 수 있게 해 주는 다양한 것들이 있습니다. 이 중 lambda라는 것이 있는데 이것을 사용하면 알고리즘에서 조건자를 사용할 때 지금보다 훨씬 더 편하게 기술할 수 있습니다. STL을 공부한 이 후에는 C++0x을 공부하시기를 바랍니다.
'잡다한것들전부 > c++ STL' 카테고리의 다른 글
| [펌] About STL : C++ STL 프로그래밍(10)-알고리즘2 (0) | 2014.01.10 |
|---|---|
| [펌] About STL : C++ STL 프로그래밍(9)-알고리즘1 (0) | 2014.01.10 |
| [펌] About STL : C++ STL 프로그래밍(8)-셋(Set) (0) | 2014.01.10 |
| [펌] About STL : C++ STL 프로그래밍(7)-맵(Map) (0) | 2014.01.10 |
| [펌] About STL : C++ STL 프로그래밍(6)-해시 맵(Hash Map) (0) | 2014.01.10 |
| [펌] About STL : C++ STL 프로그래밍(5)-덱(deque) : (2) (0) | 2014.01.10 |


