1 / 44

표준 템플릿 라이브러리

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

kelli
Download Presentation

표준 템플릿 라이브러리

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 표준 템플릿 라이브러리 Standard Template Library (C++로 배우는 객체지향 프로그래밍,7장)

  2. 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 같은 반복 구조의 고급형 대안으로 제공

  3. STL을 사용하는 이유 • STL 컨테이너 • 효율성 • 크기가 가변적 : C++ 배열과 달리 원소가 삽입되면, 크기가자동으로 늘어나고 원소가 삭제되면 자동으로 줄어듬 • 배열 오버플로 검사나 배열을 위한 기억장소를 동적으로 할당할 필요가 없음 • 프로그래밍이 용이하고 프로그램 오류가 적어지며 저장장치를 효율적으로 운용하는 효과 • 다양한 형태의 컨테이너(예: vector, associative array, set, stack, queue,…)를 제공 • 3가지 유형 : First-class containers, Adapters, Near containers • 컨테이너에 대한 시간 및 공간 복잡도(complexity)가 공표되어 있음

  4. STL을 사용하는 이유 • STL 알고리즘 • 컨테이너를 위한 다양한 알고리즘 제공 • copy, sort, search, merge, permute, replace, reverse, … • 직관적이고 적용하기 쉬우며, 전역함수이므로 사용할 경우, 전체 코드의 readability 증가 • 내장형 반복구조 제공 • for_each • 융통성(flexiblity) • copy : 집합  집합, 집합  디스크 파일 간 복사 가능 vector< int > v; // fill up v with values for_each( v.begin(), v.end(), sq ); // 각 원소의 제곱

  5. STL을 사용하는 이유 • STL 반복자 • STL 컨테이너와 알고리즘을 융통성과 효율성 있도록 만들어줌 • 포인터와 유사하게 동작 • first-class 컨테이너들의 개별 원소를 가리키는데 사용됨 • 내용참조 연산자(*)로 현재 가리키는 원소를 액세스 • ++연산자를 사용하여 iterator를 컨테이너의 다음 원소로 이동 • 프로그래머가STL 반복자를 포인터가 아닌 것처럼 사용할 수 있게 허용하는 고급 구조

  6. 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에 모두 동일한 방법으로 적용됨

  7. STL을 사용하는 이유 • STL의 장점 • 효율성 • 융통성 • 사용 용이성 • 확장성 • 사용자가 새로운 컨테이너와 알고리즘을 추가할 수 있음 • STL 알고리즘은 내장형이나 사용자 정의형 컨테이너 상에서 사용 가능 • 사용자 정의형 알고리즘은 내장형이나 사용자 정의 컨테이너에 적용 가능 • STL 도구 집합 • 대규모이고 복잡한 응용 개발에 효과적

  8. 기본적인 컨테이너 • First-class STL 컨테이너(7가지) • 순차형(sequential)과 결합형(associative)

  9. 기본적인 컨테이너 • 순차형 컨테이너 : list, vector, deque • vector, deque • 원소가 위치에 의해, 인덱스를 사용하여 액세스 가능(배열과 유사) • list : 양방향 연결 리스트 • 원소 액세스를 위한 begin이나 end와 같은 멤버함수 제공 • 결합형컨테이너 : map, multimap, set, multiset • 컨테이너 내의 원소는 키로 액세스 예) m이 부동소수점 형태의 국민 총 생산량(GNP)을 저장하는 STL map이며 키로 국가 명을 사용한다면, float gnp = m[ “korea” ];

  10. 기본적인 순차형 컨테이너: 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() : 벡터의 현재 크기를 반환 • 연산자 []의 중복정의

  11. 기본적인 순차형 컨테이너: vector, deque 및 list • vector클래스 인스턴스 정의 • vector의 초기 크기를 명시하지 않는 경우 : 일반적 vector< double > d; • vector의 초기 크기를 명시하는 경우 : 모든 원소는 0으로 초기화 vector< double > d( 1000 ); • vector클래스 주요 멤버 함수 • begin() • 컨테이너가 not empty면 컨테이너의 첫 번째 원소를 가리키는 반복자 반환 • 컨테이너가 empty면 컨테이너의 끝 바로 다음을 가리키는 반복자 반환 • end() • 컨테이너의 끝 바로 다음을 가리키는 반복자 반환

  12. 기본적인 순차형 컨테이너: vector, deque 및 list • vector와 deque의 비교 • 그림 7.3.2 의 프로그램에 대해, #include <vector>  #include <deque> vector< int > nums;  deque< int > nums; 로 교체했을 때의, 출력은? • vector와 deque는 구현 상(특히 삽입과 삭제)에서 차이 • vector : 앞에 삽입하는 것이 끝에 삽입하는 것보다 비효율적 • deque : 삽입과 삭제가 앞쪽에서나 뒤쪽 어느 곳에서 일어나든 효율 면에서는 동일

  13. 기본적인 순차형 컨테이너: 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" );// ChengwenKamiko Andre names.insert( names.begin(), "Maria" ); dump( names ); // Maria ChengwenKamiko Andre names.reverse(); // 리스트를 역전 cout << endl; dump( names ); // Andre KamikoChengwen Maria return 0; }

  14. (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 컨테이너의 원소를 변경하지 않는다

  15. vector, deque 및 list의 효율성 • 유사점 • insert, erase멤버 함수 등 • 차이점 • [] : vector, deque에서만 오버로딩 됨 • 연산의 효율성(time, storage) : 그림 7.3.5. vector deque list

  16. 기본적인 결합형 컨테이너: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

  17. 기본적인 결합형 컨테이너: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; }

  18. 기본적인 결합형 컨테이너: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; } value key

  19. 컨테이너 어댑터 • 컨테이너 어댑터(adaptor) • first-class 컨테이너가 아님 • 실제 데이터 구조에 대한 구현을 제공하지 않음 - 사용자가 원하는 데이터 구조를 선택 가능 • 반복자(iterators)를 지원하지 않음 • 공통 멤버 함수 • push – 데이터 구조에 하나의 원소를 삽입 • pop – 데이터 구조로부터 하나의 원소를 삭제 • 종류 : stack, queue, priority_queue • stack어댑터 : LIFO(List In First Out) 리스트 생성 • queue어댑터 : FIFO(First In First Out) 리스트 생성 • priority_queue어댑터 : 우선순위 순으로 원소를 삭제하는 큐 생성

  20. 컨테이너 어댑터 • 예제 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;

  21. (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

  22. 컨테이너 어댑터 • 예제 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의 앞쪽 원소를 액세스

  23. 컨테이너 어댑터 • 예제 7.3.8. : STL priority_queue 어댑터(그림 7.3.10.) 8614 21890 3936 20054 3142 1191 *** Priority by value: 21890 20054 8614 3936 3142 1191 //… #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; } • vector 또는 deque로구현 : 디폴트는 vector • push() : 원소 삽입 • pop() : 원소 삭제 • top() : 다음 원소를 삭제하지 않으면서 반환 원소가 정렬된 순서로 삽입되고, front에서 삭제됨 • 원소들은 우선 순위에 따라 삽입됨 • 가장 우선순위가 높은 원소가 먼저 삭제됨 • 힙정렬(heapsort)에 의해 정렬된 순서를 유지

  24. 기타 컨테이너 • string, bitset 클래스 • string 클래스 • bitset 클래스 • 01010101과 같은 이진 비트열(sequence or string of bits)

  25. 기타 컨테이너 • 예제 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> 필요

  26. (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

  27. 기타 컨테이너 • 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

  28. 기타 컨테이너 • 예제 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;// 00010000 class 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(); }

  29. (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; }; • 개개의 비트가 인덱스를 통해 access되도록 중복정의 • 해당 비트가 1이면 true, 0이면 false를 반환

  30. (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

  31. 알고리즘 • STL 알고리즘 • 종류 : 정렬 및 탐색, 수치 처리, 집합 연산, 복사 등 • 템플릿 함수로 구현(cf.STL 컨테이너 : 템플릿 클래스로 구현) • 예) STL reverse 알고리즘 프로토타입 • vector와 deque등에 똑같이 동작 • 컨테이너의 원소를 반복자를 사용하여 액세스하여 역순으로 놓음 template< class BidirectionalIterator > // 템플릿 헤더 void reverse( BidirectionalIterator it1, // 반복자1 BidirectionalIterator it2 ); // 반복자2

  32. 알고리즘 • 예제 7.3.11. STL 알고리즘 generate, replace_if, sort 및 for_each(그림 7.2.13) //… #include <algorithm> //*** for STL algorithm using namespace std; void dump( int i ) { cout << i << endl; } bool odd( int i ) { return i % 2 != 0; } bool comp( constint& i1, constint& 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; }

  33. (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, Generatorg);

  34. (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);

  35. (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);

  36. (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);

  37. 알고리즘 • 예제 7.3.12. STL 알고리즘 nth_element, random_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, " " ) ); } 출력 스트림에 쓰여질 요소간의 분리자

  38. (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 mno 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

  39. (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);

  40. (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);

  41. (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 );

  42. 알고리즘 • 예제 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 );

  43. (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 ); • 역순으로 복사

  44. 참고 : C++ 파일처리 • 헤더 fstream을 포함 ifstream infile; // 파일을 읽고 쓰기 위한 변수 선언 ofstream outfile; infile.open( "income.in" ); //변수와 파일 연결 outfile.open( "tax.out" ); if ( infile >> income ) // 파일이 열려있다면 true // … infile.close(); // 파일 닫기 outfile.close();

More Related