표준 템플릿 라이브러리

44
C++ 로 로로로 로로로로 로로로로로 1 로로 로로로 로로로로로 Standard Template Library (C++ 로 로로로 로로로로 로로로로로 , 7 로 )

Upload: kelli

Post on 25-Jan-2016

89 views

Category:

Documents


5 download

DESCRIPTION

표준 템플릿 라이브러리. Standard Template Library (C++ 로 배우는 객체지향 프로그래밍 , 7 장 ). 7.3. 표준 템플릿 라이브러리. STL(Standard Template Library) 표준 C++ 라이브러리의 일부 데이터 구조 + 연산 ( 알고리즘 ) 기본 구성 요소 컨테이너 (container) : 데이터 구조 vector, stack, queue, dequeue , list, set, map, … 알고리즘 (algorithm) - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: 표준  템플릿 라이브러리

1C++ 로 배우는 객체지향 프로그래밍

표준 템플릿 라이브러리

Standard Template Library

(C++ 로 배우는 객체지향 프로그래밍 , 7장 )

Page 2: 표준  템플릿 라이브러리

2Chapter 7: 템플릿과 표준 템플릿 라이브러리

7.3. 표준 템플릿 라이브러리

STL(Standard Template Library) 표준 C++ 라이브러리의 일부 데이터 구조 + 연산 ( 알고리즘 )

기본 구성 요소 컨테이너 (container) : 데이터 구조

vector, stack, queue, dequeue, list, set, map, … 알고리즘 (algorithm)

데이터 구조를 처리하기 위한 프로시저 ( 함수 ) container copy, sort, search, merge, permute,…

반복자 (iterator) 한번에 하나씩 컨테이너 안의 원소를 액세스하기 위한 메커니즘 컨테이너를 임의의 방향으로 ( 앞 뒤 , 뒤 앞 , …) 이동 가능 for 나 while 같은 반복 구조의 고급형 대안으로 제공

Page 3: 표준  템플릿 라이브러리

3Chapter 7: 템플릿과 표준 템플릿 라이브러리

STL 을 사용하는 이유

STL 컨테이너 효율성

크기가 가변적 : C++ 배열과 달리 원소가 삽입되면 , 크기가 자동으로 늘어나고 원소가 삭제되면 자동으로 줄어듬

배열 오버플로 검사나 배열을 위한 기억장소를 동적으로 할당할 필요가 없음

프로그래밍이 용이하고 프로그램 오류가 적어지며 저장장치를 효율적으로 운용하는 효과

다양한 형태의 컨테이너 ( 예 : vector, associative array, set, stack, queue,…) 를 제공

3 가지 유형 : First-class containers, Adapters, Near containers

컨테이너에 대한 시간 및 공간 복잡도 (complexity) 가 공표되어 있음

Page 4: 표준  템플릿 라이브러리

4Chapter 7: 템플릿과 표준 템플릿 라이브러리

STL 을 사용하는 이유

STL 알고리즘 컨테이너를 위한 다양한 알고리즘 제공

copy, sort, search, merge, permute, replace, reverse, …

직관적이고 적용하기 쉬우며 , 전역 함수이므로 사용할 경우 , 전체 코드의 readability 증가

내장형 반복구조 제공 for_each

융통성 (flexiblity) copy : 집합 집합 , 집합 디스크 파일 간 복사 가능

vector< int > v;// fill up v with valuesfor_each( v.begin(), v.end(), sq ); // 각 원 소 의 제곱

Page 5: 표준  템플릿 라이브러리

5Chapter 7: 템플릿과 표준 템플릿 라이브러리

STL 을 사용하는 이유

STL 반복자 STL 컨테이너와 알고리즘을 융통성과 효율성 있도록 만들어줌 포인터와 유사하게 동작

first-class 컨테이너들의 개별 원소를 가리키는데 사용됨 내용참조 연산자 (*) 로 현재 가리키는 원소를 액세스 ++ 연산자를 사용하여 iterator 를 컨테이너의 다음 원소로 이동

프로그래머가 STL 반복자를 포인터가 아닌 것처럼 사용할 수 있게 허용하는 고급 구조

Page 6: 표준  템플릿 라이브러리

6Chapter 7: 템플릿과 표준 템플릿 라이브러리

STL 을 사용하는 이유

예제 7.3.1. : STL 알고리즘의 융통성을 보여주는 예

deque 와 vector 는 오름차순 (default) 으로 정렬됨

#include <vector>#include <deque>#include <algorithm>using namespace std;int main() { vector< int > v; deque< double > d; //v 는 정수로 d 는 부동소수점 수로 채움 sort( v.begin(), v.end() ); sort( d.begin(), d.end() ); //…}

sort 알 고 리 즘 이 deque 와 vector 에 모 두 동 일 한 방 법 으 로 적용됨

Page 7: 표준  템플릿 라이브러리

7Chapter 7: 템플릿과 표준 템플릿 라이브러리

STL 을 사용하는 이유

STL 의 장점 효율성 융통성 사용 용이성 확장성

사용자가 새로운 컨테이너와 알고리즘을 추가할 수 있음 STL 알고리즘은 내장형이나 사용자 정의형 컨테이너 상에서 사용

가능 사용자 정의형 알고리즘은 내장형이나 사용자 정의 컨테이너에 적용

가능 STL 도구 집합

대규모이고 복잡한 응용 개발에 효과적

Page 8: 표준  템플릿 라이브러리

8Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 컨테이너

First-class STL 컨테이너 (7 가지 ) 순차형 (sequential) 과 결합형 (associative)

컨테이너 타입 설명

list 순차형 양방향 연결 리스트 (doubly-linked list)

vector 순차형 필요하면 신축성 있게 늘어나거나 줄어드는 배열

deque 순차형 어느 쪽에서나 효율적으로 삽입 / 삭제되는 배열

set 결합형 중복되지 않은 키 집합

multiset 결합형 중복이 허용되는 set

map 결합형 키로 액세스되는 중복이 없는 (key, value) 집합

multimap 결합형 중복이 허용되는 map

Page 9: 표준  템플릿 라이브러리

9Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 컨테이너

순차형 컨테이너 : list, vector, deque vector, deque

원소가 위치에 의해 , 인덱스를 사용하여 액세스 가능 ( 배열과 유사 )

list : 양방향 연결 리스트 원소 액세스를 위한 begin 이나 end 와 같은 멤버 함수 제공

결합형 컨테이너 : map, multimap, set, multi-set 컨테이너 내의 원소는 키로 액세스 예 ) m 이 부동소수점 형태의 국민 총 생산량 (GNP) 을 저장하는 STL

map 이며 키로 국가 명을 사용한다면 ,

float gnp = m[ “korea” ];

Page 10: 표준  템플릿 라이브러리

10Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 순차형 컨테이너 : vector, deque 및 list

예제 7.3.2.#include <iostream>#include <vectors>using namespace std;int main() { int i; vector< int > nums; nums.insert( nums.begin(), -999 ); // -999 nums.insert( nums.begin(), 14 ); // 14 -999 nums.insert( nums.end(), 57 ); // 14 -999 57 for( i =0; i < nums.size(); i++) cout << nums[ i ] << endl; // 14 -999 57 cout << endl; nums.erase( nums.begin() ); // -999 57 nums.erase( nums.begin() ); // 57 for( i =0; i < nums.size(); i++) cout << nums[ i ] << endl; // 57 return 0;}

14 -999 57 57

erase() : 벡 터 로 부 터 원 소 를 제거

size() : 벡터의 현재 크기를 반환 연산자 [] 의 중복정의

Page 11: 표준  템플릿 라이브러리

11Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 순차형 컨테이너 : vector, deque 및 list

vector 클래스 인스턴스 정의 vector 의 초기 크기를 명시하지 않는 경우 : 일반적 vector< double > d; vector 의 초기 크기를 명시하는 경우 : 모든 원소는 0 으로

초기화 vector< double > d( 1000 );

vector 클래스 주요 멤버 함수 begin() 컨 테 이 너 가 not empty 면

컨테이너의 첫 번째 원소를 가리키는 반복자 반환

컨테이너가 empty 면 컨테이너의 끝 바로 다음을 가리키는 반복자 반환

end() 컨테이너의 끝 바로 다음을 가리키는

반복자 반환

v.begin()

3.14 3.14 3.14

v.end()

Page 12: 표준  템플릿 라이브러리

12Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 순차형 컨테이너 : vector, deque 및 list

vector 와 deque 의 비교 그림 7.3.2 의 프로그램에 대해 , #include <vector> #include <deque> vector< int > nums; deque< int > nums;

로 교체했을 때의 , 출력은 ?

vector 와 deque 는 구현 상 ( 특히 삽입과 삭제 ) 에서 차이 vector : 앞에 삽입하는 것이 끝에 삽입하는 것보다 비효율적 deque : 삽입과 삭제가 앞쪽에서나 뒤쪽 어느 곳에서 일어나든

효율 면에서는 동일

Page 13: 표준  템플릿 라이브러리

13Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 순차형 컨테이너 : vector, deque 및 list

예제 7.3.3. STL list 컨테이너 ( 그림 7.3.4 )#include <iostream>#include <string>#include <list>using namespace std;void dump( list< string >& );int main() { list< string > names; // 리스트에 4 개의 원소를 삽입 names.insert( names.begin(), "Kamiko" ); // Kamiko names.insert( names.end(), "Andre" ); // Kamiko Andre names.insert( names.begin(), "Chengwen" );// Chengwen Kamiko Andre names.insert( names.begin(), "Maria" ); dump( names ); // Maria Chengwen Kamiko Andre names.reverse(); // 리스트를 역전 cout << endl; dump( names ); // Andre Kamiko Chengwen Maria return 0;}

Page 14: 표준  템플릿 라이브러리

14Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

관련 반복자 type

void dump( list< string >& l ) { list< const string >::const_iterator it; // 리 스 트 반복자 // 리스트를 표준 출력에 인쇄 it = l.begin(); // 반복자 초기화 while ( it != l.end() ) { // 반복자가 끝에 있는가 ? cout << *it << endl; it++; // 반복자 증가 }}

list< int > vector< double >

list< int >::iterator

list< int >::const_iterator

vector< double >::iterator

vector< double >::const_iterator

컨테이너의 원소를 변경하지 않는다

Page 15: 표준  템플릿 라이브러리

15Chapter 7: 템플릿과 표준 템플릿 라이브러리

vector, deque 및 list 의 효율성

유사점 insert, erase 멤버 함수 등

차이점 [] : vector, deque 에서만 오버로딩 됨 연산의 효율성 (time, storage) : 그림 7.3.5.

연산 vector deque list

앞 부분에서 삽입 / 제거 선형 상수 상수

끝 부분에서 삽입 / 제거 상수 상수 상수

중간 부분에서 삽입 / 제거 선형 선형 상수

첫 번째 원소 액세스 상수 상수 상수

마지막 원소 액세스 상수 상수 상수

중간 부분 원소 액세스 상수 상수 선형

vector

deque

list

Page 16: 표준  템플릿 라이브러리

16Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 결합형 컨테이너 :set, multiset 및 multimap

2 개 그룹 : sets, maps set

0 개 이상의 중복되지 않는 원소 Non-duplicated key 들의 정렬되지 않은 집합 예 ) { 잡스 , 게이츠 , 엘리슨 }

multiset : duplicated key 를 허용하는 set map

0 개 이상의 정렬되지 않은 쌍의 집합 (non-duplicated key, key 와 연관된 값 ) 예 ) {( 잡스 , 애플 ), ( 게이츠 , 마이크로소프트 ), ( 엘리슨 ,

오라클 ) } multimap : duplicate key 를 허용하는 map

Page 17: 표준  템플릿 라이브러리

17Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 결합형 컨테이너 :set, multiset 및 multimap

예제 7.3.4. 그림 7.3.6 :

STL set 컨테이너

#include <iostream>#include <set>using namespace std;int main() { set< int > s; s.insert( -999 ); s.insert( 18 ); s.insert( 321 ); s.insert( -999 ); // duplicated! set< int >::const_iterator it; it = s.begin(); while ( it != s.end() ) cout << *it++ << endl; // -999 18 321 순 int key; cout << “Enter an integer: "; cin >> key; it = s.find( key ); if( it == s.end() ) // not found cout << key << " is not in set." << endl; else cout << key << " is in set." << endl; return 0;}

Page 18: 표준  템플릿 라이브러리

18Chapter 7: 템플릿과 표준 템플릿 라이브러리

기본적인 결합형 컨테이너 :set, multiset 및 multimap

예제 7.3.5. STL map 컨테이너 ( 그림 7.3.7 )

#include <iostream>#include <string>#include <map>using namespace std;int main() { map< string, int > m; m[ "zero" ] = 0; m[ "one" ] = 1; m[ "two" ] = 2; m[ "three"] = 3; m[ "four" ] = 4; m[ "five" ] = 5; m[ "six" ] = 6; m[ "seven"] = 7; m[ "eight"] = 8; m[ "nine" ] = 9; cout << m[ "three" ] << endl // 3 << m[ "five" ] << endl // 5 << m[ "seven" ] << endl; // 7 return 0;}

key value

Page 19: 표준  템플릿 라이브러리

19Chapter 7: 템플릿과 표준 템플릿 라이브러리

컨테이너 어댑터

컨테이너 어댑터 (adaptor) first-class 컨테이너가 아님

실제 데이터 구조에 대한 구현을 제공하지 않음 - 사용자가 원하는 데이터 구조를 선택 가능

반복자 (iterators) 를 지원하지 않음 공통 멤버 함수

push – 데이터 구조에 하나의 원소를 삽입 pop – 데이터 구조로부터 하나의 원소를 삭제

종류 : stack, queue, priority_queue stack 어댑터 : LIFO(List In First Out) 리스트 생성 queue 어댑터 : FIFO(First In First Out) 리스트 생성 priority_queue 어댑터 : 우선순위 순으로 원소를 삭제하는

큐 생성

Page 20: 표준  템플릿 라이브러리

20Chapter 7: 템플릿과 표준 템플릿 라이브러리

컨테이너 어댑터

예제 7.3.6. : STL stack 어댑터 ( 그림 7.3.8.)#include <iostream>#include <stack>#include <cctype>using namespace std;int main() { const string prompt = "Enter an algebraic expression: "; const char lParen = '('; const char rParen = ')'; stack< char > s; //*** STL stack; string buf;

원소 : 디폴트는 deque

stack< char > s; stack< char, deque< char > > s; stack 에 vector 를 적용하려면 ,

stack< char, vector< char > > s;

Page 21: 표준  템플릿 라이브러리

21Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

//*** 완전한 괄호로 둘러싸인 산술식을 표준 입력에서 읽어들인다 . cout << prompt << endl; getline( cin, buf ); for ( int i = 0; i < buf.length(); i++) if( !isspace( buf[ i ] ) s.push( buf[ i ] ); cout << "Original expression: " << buf << endl; cout << "Expression in reverse: "; // 스택에서 문자를 꺼내 오른쪽 괄호와 왼쪽 괄호를 서로 바꾼다 . while ( !s.empty() ) { char t = s.top(); // top 원소를 가져온다 . s.pop(); // top 원소를 제거한다 . if ( t == lParen ) t = rParen; else if ( t == rParen ) t = lParen; cout << t; } cout << endl; return 0;}

top() : top 원소를 삭제하지 않으면서 반환

pop() : top 원 소 를 삭제하지만 반환 타입은 void

Page 22: 표준  템플릿 라이브러리

22Chapter 7: 템플릿과 표준 템플릿 라이브러리

컨테이너 어댑터

예제 7.3.7. : STL queue 어댑터 ( 그림 7.3.9)

#include <iostream>#include <queue>using namespace std;int main() { queue< int > q; // == queue< int, deque< int > > q.push( 1 ); q.push( 3 ); q.push( 5 ); q.push( 7 ); q.push( 11 ); q.push( 13 ); // 큐가 빌 때까지 꺼내 인쇄 : 출력은 1 3 5 7 11 13 while( !q.empty ) { cout << q.front() << endl; // 정수 반환 q.pop(); // void 반환 } return 0;}

원소 : 디폴트는 deque push() : 원소 삽입 pop() : 원소 삭제 front() : queue 의 앞 쪽 원 소 를

액세스

Page 23: 표준  템플릿 라이브러리

23Chapter 7: 템플릿과 표준 템플릿 라이브러리

컨테이너 어댑터

예제 7.3.8. : STL priority_queue 어댑터 ( 그림 7.3.10.)//… #include 부분 생략int main() { const int howMany = 8; int i; priority_queue< int > nums; srand( time( 0 ) ); // seed rand for ( i = 0; i < howMany; i++ ) int next = rand(); cout << next << endl; nums.push( next ); } for ( i = 0; i < howMany; i++ ) { cout << nums.top() << endl; nums.pop(); // 원소 제거 } return 0;}

8614 21890 3936 20054 3142 1191 *** Priority by value: 21890 20054 8614 3936 3142 1191

vector 또는 deque 로 구현 : 디폴트는 vec-tor

push() : 원소 삽입 pop() : 원소 삭제 top() : 다음 원소를 삭제하지 않으면서 반환

원 소 가 정 렬 된 순 서 로 삽 입 되 고 , front 에 서 삭제됨 • 원소들은 우선 순위에 따라 삽입됨 • 가장 우선순위가 높은 원소가 먼저 삭제됨 • 힙정렬 (heapsort) 에 의해 정렬된 순서를 유지

Page 24: 표준  템플릿 라이브러리

24Chapter 7: 템플릿과 표준 템플릿 라이브러리

기타 컨테이너

string, bitset 클래스 string 클래스 bitset 클래스

01010101 과 같은 이진 비트열 (sequence or string of bits)

Page 25: 표준  템플릿 라이브러리

25Chapter 7: 템플릿과 표준 템플릿 라이브러리

기타 컨테이너

예제 7.3.9. STL 알고리즘에 의한 string 조작 프로그램#include <iostream>#include <string>#include <algorithm>using namespace std;void printChar( char c ) { cout << c;}int main() { string s = "pele, the greatest ever"; cout << “s : " << s << endl; cout << "s in reverse: "; for_each( s.rbegin(), s.rend(), printChar ); cout << endl; char* where = find( s.begin(), s.end(), 'a' ); cout << 'a' is the " << where - s.begin() + 1 << "th char in: " << s << endl;

string 클래스 표준 STL 컨테이너의 begin 과

end 메소드를 가짐 STL 알 고 리 즘 을 사 용 하려면 ,

#include <algorithm> 필요

Page 26: 표준  템플릿 라이브러리

26Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

random_shuffle( s.begin(), s.end() ); cout << "s after a random shuffle: " << s << endl; where = find( s.begin(), s.end(), 'a' ); cout << "'a' is the " << where - s.begin() + 1 << "th char in: " << s << endl; sort( s.begin(), s.end() ); cout << "sorted in ascending order: " << s << endl; return 0;}

s: pele, the greatest ever s in reverse: reve tsetaerg eht ,elep 'a' is the 14th char in: pele, the greatest ever s after a random shuffle: ,eptgeer etsht evlreae 'a' is the 21th char in: ,eptgeer etsht evlreae sorted in ascending order: ,aeeeeeeehlprrstttv

Page 27: 표준  템플릿 라이브러리

27Chapter 7: 템플릿과 표준 템플릿 라이브러리

기타 컨테이너

bitset 클래스 이진수로 정수를 표현하는데 사용

변환생성자 bitset( unsigned long n ); // n 을 이진수로 나타낸 bitset 을 생성

예 : bitset< 8 > bs( 9 );

멤버 함수 특정 비트를 0 이나 1 로 만드는 멤버 함수 특정 비트 혹은 모든 비트를 한번에 역으로 하는 멤버 함수 특정 비트가 0 으로 되어 있는지 또는 1 로 되어 있는지 검사하는 멤버 함수 비트를 왼쪽이나 오른쪽으로 시프트하는 멤버 함수 and, or 및 exclusive-or 와 같은 표준이진 연산을 수행하는 멤버 함수 bitset 을 string 타입이나 unsigned long 타입 정수로 바꾸는 멤버

함수

#include <bitset> using namespace std; bitset< 8 > bs1; // 8 bits bitset< 128 > bs2; // 128 bits

Page 28: 표준  템플릿 라이브러리

28Chapter 7: 템플릿과 표준 템플릿 라이브러리

기타 컨테이너

예 제 7.3.10. 그 림

7.3.12. bitset 컨테이너

#include <iostream>#include <bitset>using namespace std;const featureCount = 8;const unsigned Framed = 1; // 00000001 const unsigned Bordered = 2; // 00000010 const unsigned StdMenu = 4; // 00000100 const unsigned ToolBar = 8; // 00001000 const unsigned StatusBar = 16;// 00010000class Window {public: Window( const string& n, unsigned f ) { name = n; features = bitset< featureCount > ( f ); createWindow(); } Window( const char* n, unsigned f ) { name = n; features = bitset< featureCount > ( f ); createWindow(); }

Page 29: 표준  템플릿 라이브러리

29Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

private: void createWindow() { cout << "\n*** Window features for " << name << " given bit mask " << features << ":" << endl; if ( features[ 0 ] ) // 1st bit set? (rightmost is 1st) cout << "\t" << "framed" << endl; if ( features[ 1 ] ) // 2nd bit set? cout << "\t" << "bordered" << endl; if ( features[ 2 ] ) // 3rd bit set? cout << "\t" << "with standard menu" << endl; if ( features[ 3 ] ) // 4th bit set? cout << "\t" << "with tool bar" << endl; if ( features[ 4 ] ) // 5th bit set? cout << "\t" << "with status bar" << endl; } string name; bitset< featureCount > features;};

개개의 비트가 인덱스를 통해 ac-cess 되도록 중복정의

해당 비트가 1 이면 true, 0 이면 false 를 반환

Page 30: 표준  템플릿 라이브러리

30Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

출력

int main() { Window w1( "w1", Framed | ToolBar | StatusBar ); Window w2( "w2", ToolBar | Framed | StatusBar ); Window w3( "w3", Framed | StdMenu | StatusBar | ToolBar

| Bordered ); return 0;}

*** Window features for w1 given bit mask 00011001: framed with tool bar with status bar*** Window features for w2 given bit mask 00011001: framed with tool bar with status bar*** Window features for w3 given bit mask 00011111: framed bordered with standard menu with tool bar with status bar

Page 31: 표준  템플릿 라이브러리

31Chapter 7: 템플릿과 표준 템플릿 라이브러리

알고리즘

STL 알고리즘 종류 : 정렬 및 탐색 , 수치 처리 , 집합 연산 , 복사 등 템플릿 함수로 구현 (cf. STL 컨테이너 : 템플릿 클래스로

구현 ) 예 ) STL reverse 알고리즘 프로토타입

vector 와 deque 등에 똑같이 동작 컨테이너의 원소를 반복자를 사용하여 액세스하여 역순으로 놓음

template< class BidirectionalIterator > // 템 플 릿 헤더void reverse( BidirectionalIterator it1, // 반복자 1 BidirectionalIterator it2 ); // 반복자 2

Page 32: 표준  템플릿 라이브러리

32Chapter 7: 템플릿과 표준 템플릿 라이브러리

알고리즘

예제 7.3.11. STL 알고리즘 generate, replace_if, sort 및 for_each( 그림 7.2.13)

//…#include <algorithm> //*** for STL algorithmusing namespace std;void dump( int i ) { cout << i << endl; }bool odd( int i ) { return i % 2 != 0; }bool comp( const int& i1, const int& i2 ) { return i1 > i2; } int main() { vector< int > v( 10 ); // 10 개의 정수로 된 벡터 // 임의의 정수로 채운다 . generate( v.begin(), v.end(), rand ); // 홀수는 0 으로 대치한다 . replace_if( v.begin(), v.end(), odd, 0 ); // 내림차순으로 정렬 sort( v.begin(), v.end(), comp ); for_each( v.begin(), v.end(), dump ); // 인쇄 return 0;}

Page 33: 표준  템플릿 라이브러리

33Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

generate

범위 [first, last) 를 함수 또는 함수 객체 g 를 last - first 번 호출해서 생성되는 값들로 채움

시간 복잡도 : 선형 예 ) generate( v.begin(), v.end(), rand );

#include <algorithm>template<class ForwardIt, class Generator>void generate(ForwardIt first, ForwardIt last, Generator g);

Page 34: 표준  템플릿 라이브러리

34Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

replace_if

범위 [first, last) 에서 서술 p 를 만족하는 모든 원소를 new로 대치

시간 복잡도 : 선형 예 ) replace_if( v.begin(), v.end(), odd, 0 );

#include <algorithm>template<class ForwardIt, class Pred, class T>void replace_if(ForwardIt first, ForwardIt last,

Pred p, const T& new);

Page 35: 표준  템플릿 라이브러리

35Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

sort

범위 [first, last) 내의 원소들을 정렬 정렬 방법 :

Version1 : 원소들을 비교하기 위해 < 를 사용 Version2 : 비교 서술 comp 를 사용

평균 시간 복잡도 : n log n ( n : 정렬될 시퀀스의 길이 ) 예 ) sort( v.begin(), v.end(), comp );

#include <algorithm>template<class RandomAccessIt>void sort(RandomAccessIt first, RandomAccessIt last);template<class RandomAccessIt, class Compare>void sort(RandomAccessIt first, RandomAccessIt last,

Compare comp);

Page 36: 표준  템플릿 라이브러리

36Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

for_each

반복자에 의해 그 내용이 참조되는 범위 [first, last) 안에 있는 각 원소에 함수 f 를 한번씩 적용시킴

시간 복잡도 : 선형 예 ) for_each( v.begin(), v.end(), dump );

#include <algorithm>template<class InputIt, class Func>Func for_each(InputIt first, InputIt last, Func f);

Page 37: 표준  템플릿 라이브러리

37Chapter 7: 템플릿과 표준 템플릿 라이브러리

알고리즘

예제 7.3.12. STL 알고리즘 nth_element, ran-dom_shuffle, copy( 그림 7.3.14)

main(){ const int len = 27; const int med = len / 2; char alph[] = "abcdefghijklmnopqrstuvwxyz{"; // 27 print( "\n\nOriginal array:\n", alph, len ); random_shuffle(alph, alph + len ); print( "\n\nAfter random-shuffle:\n", alph, len ); nth_element( alph, alph+med, alph+len ); print( "\n\nAfter nth elemnet:\n", alph, len); print( "\n\t < median: ", alph, med ); print( "\n\t median: ", alph + med, 1 ); print( "\n\t > median: ", alph + med + 1, len / 2 ); cout << endl; return 0;}void print( const char* msg, char a[], int len ) { cout << msg; copy( a, a + len, ostream_iterator< char >( cout, " " ) );}

출력 스트림에 쓰여질 요소간의 분리자

Page 38: 표준  템플릿 라이브러리

38Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

출력 예

Original array: a b c d e f g h i j k l m n o p q r s t u v w x y z { After random_shuffle: e t a r k m { l s y g q h o j x u z w p n b f d v c i After nth element: e i a c d f b h g j k l m n o p q r s t u v { w z x y < median: e i a c d f b h g j k l m median: n > median: o p q r s t u v { w z x y

Page 39: 표준  템플릿 라이브러리

39Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

random_shuffle

의사 난수를 발생시키는 rand 와 같은 함수를 사용하여 무작위로 범위 [first, last) 내의 원소들을 재배열

결과로 생성되는 순열들은 uniform 하게 분포됨 Version 2 : 특정 난수 발생 함수 g 를 매개 변수로 가짐 시간 복잡도 : 선형 예 ) random_shuffle( alph, alph + len );

#include <algorithm>template<class RandomAccessIt>void random_shuffle(RandomAccessIt first, RandomAccessIt last);template<class RandomAccessIt, class RandomnumberGen>void random_shuffle(RandomAccessIt first, RandomAccessIt last,

RandomNumberGen& g);

Page 40: 표준  템플릿 라이브러리

40Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

nth_element

전체 범위가 정렬되어 있다면 , 정렬된 순서에 맞도록 위치 pos 에 1 개의 원소를 놓음

any element to the left of pos any element to the right of pos

Version1 : < 가 원소 비교를 위해 사용됨 Version2 : comp 가 원소 비교를 위해 사용됨 평균 시간 복잡도 : 선형 예 ) nth_element( alph, alph+med, alph+len );

#include <algorithm>template<class RandomAccessIt>void nth_element(RandomAccessIt first,

RandomAccessIt pos, RandomAccessIt last);template<class RandomAccessIt, class Compare>void nth_element(RandomAccessIt first, RandomAccessIt pos,

RandomAccessIt last, Compare comp);

Page 41: 표준  템플릿 라이브러리

41Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

copy

다음 조건이 만족되도록 [first1, last1) 을 [first2, last2)로 복사 last2 == first2 + ( last1 - first1 )

복사는 first1 에서 last1-1까지 진행되고 last2 를 반환 시간 복잡도 : 선형 예 ) copy( a, a + len, ostream_iterator< char >( cout, " " ) );

#include <algorithm>template< class InputIt, class OutputIt >OutputIt copy( InputIt first1, InputIt last1,

OutputIt first2 );

Page 42: 표준  템플릿 라이브러리

42Chapter 7: 템플릿과 표준 템플릿 라이브러리

알고리즘

예제 7.3.13. STL 출력 반복자 ( 그림 7.3.15.)

vector< int > fibs( 32 ); fibs[ 0 ] = fibs[ 1 ] = 1; // base case for ( int i = 2; i < 32; i++ ) fibs[ i ] = fibs[ i - 1 ] + fibs[ i - 2 ]; // 출력 스트림과 반복자 생성 ofstream outfile( "output.dat" ); ostream_iterator< int > outFileIt( outfile, " " ); ostream_iterator< int > stdOutIt( cout, "\n" ); // 출력 파일과 표준 출력에 복사 copy( fibs.begin(), fibs.end(), outFileIt ); copy( fibs.begin(), fibs.end(), stdOutIt );

Page 43: 표준  템플릿 라이브러리

43Chapter 7: 템플릿과 표준 템플릿 라이브러리

(Cont’d)

ostream_iterator ostream_iterator< int > outFileIt( outfile, “ “ );

디스크 파일과 연관된 반복자 출력을 구분하기 위해 빈칸 사용

ostream_iterator< int > stdOutIt( cout, “\n” ); 표준 출력과 연관된 반복자 출력을 구분하기 위해 newline 사용

copy copy( fibs.begin(), fibs.end(), outFileIt ); copy( fibs.begin(), fibs.end(), stdOutIt ); copy( fibs.rbegin(), fibs.rend(), stdOutIt );

역순으로 복사

Page 44: 표준  템플릿 라이브러리

44Chapter 2: C 와 C++

참고 : C++ 파일처리

헤더 fstream 을 포함ifstream infile; // 파일을 읽고 쓰기 위한 변수

선언 ofstream outfile;

infile.open( "income.in" ); // 변수와 파일 연결outfile.open( "tax.out" );

if ( infile >> income ) // 파일이 열려있다면 true

// …

infile.close(); // 파일 닫기outfile.close();