8.2(목) C++ - transform

from Study/C++ 2007/08/02 20:16 view 22891

// transform 에 대해서

int foo( int a, int b )

{

        return a + b;

}


// functional
헤더파일에서 지원한다.

template<typename T> struct plus

{

        T operator()( T a, T b )

        {

               return a+b;

        }

};

 

#include <functional>

 

void main()

{

        int x[5] = { 1, 2, 3, 4, 5 };

        int y[5] = { 1, 2, 3, 4, 5 };

        int z[5];

 

        // x~x+5 에 있는 것과 y에 있는것을 더하여 z에 넣어준다.
       
transform( x, x+5, y, z, plus<int>() );

        copy( z, z+5, ostream_iterator<int>(cout, " ") );

}

Tag |

8.2(목) C++ - 조건자

from Study/C++ 2007/08/02 20:12 view 20592

// 조건자(predicator, 술어) : bool을 리턴하는 함수 또는 함수객체

// 선형검색의 정의: 주어진 구간에서 주어진 조건을 만족하는 요소를 찾는것.

 

bool foo( int a )

{

        return a > 5;

}

 

bool goo( int a )

{

        return a % 3 == 0;

}

 

void main()

{

        int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

 

        int* p = remove_if( x, x+10, foo );

        copy( x, p, ostream_iterator<int>( cout, " " ) );

        cout << endl;

 

        int* p1 = find( x, x+10, 4 );

        int* p2 = find_if( x, x+10, goo );

        cout << *p2 << endl;

}

Tag |

8.2(목) C++ - 삽입반복자

from Study/C++ 2007/08/02 20:05 view 20978

#include <list>

#include <algorithm>

#include <iostream>

using namespace std;

 

// 삽입반복자

// 3개의 삽입반복자가 있다.

 

// 삽입반복자 함수버전의 구현

template<typename T> back_insert_iterator<T> xback_inserter( T& c )

{

        // 후방 삽입반복자 객체를 만들어서 리턴해 준다.

        // 타입을 넘겨주면서 생성자를 호출하여 리턴!
       
return back_insert_iterator<T>(c);
   

}

 

void main()

{

        int x[5] = { 1, 2, 3, 4, 5 };

 

        list<int> st(5, 1);

 

        // 삽입반복자의 객체를 만든 후 copy를 호출해도 되지만

        // 헬퍼함수를 사용해도 된다.

        copy( x, x+5, xback_inserter(st) );

 

        //front_insert_iterator<list<int> > p( st );

        //back_insert_iterator<list<int> > p( st );

        //insert_iterator<list<int> > p( st, st.begin() );

 

        //*p = 10;

        // 위코드대신push_front()를사용해도된다.

        //st.push_front( 10 );

 

        // 하지만여러개를계속넣고싶다면삽입반복자덕에copy()를사용할수있게된다.

        //copy( x, x+5, p );

 

        ostream_iterator<int> out( cout, " " );

 

        copy( st.begin(), st.end(), out );

}

Tag |

#include <iostream>

#include <iterator>

#include <algorithm>

using namespace std;


// 1. copy 알고리즘에 대해서

void main()

{

        int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        int y[10];

 

        copy( x, x+10, y );

 

        for( int i = 0; i < 10; ++i )

        {

               cout << y[i] << endl;

        }

}

 

// 2. 출력반복자

void main()

{

        ostream_iterator<int> p( cout, " " );

 

        *p = 10;       // 10을 출력한후 자동으로 ++을 수행한다.

 

//      ++p;           // 실제로는 아무일도 하지 않는다.

        *p = 20;

 

        int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

 

        // 배열을 화면에 출력하는 방법.

        copy( x, x+10, p );

}


// 3. 출력반복자 와 파일

void main()

{

        ofstream f("a.txt");   // 출력전용 파일생성.

 

        // 리스코프의 치환법칙- 부모가 들어 갈 수 있다면 자식도 들어갈 수 있다.???

        ostream_iterator<int> p( f, " " ); // 화일스트림을 가르키는 출력반복자

 

        int x[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

        copy( x, x+10, p );    //!!!

}

// 4. 입력스트림 반복자
#include <fstream>

void main()

{

        ifstream f1("a.cpp"); // 현재 소스파일의 이름을 넣으세요.

        //istream_iterator<char> p1(f1), p2;  // 디폴트생성자는 EOF를 가르킨다.

        istreambuf_iterator<char> p1(f1), p2;

        ostream_iterator<char> p3(cout, "");

        copy( p1, p2, p3 );

}

Tag |

8.1(수) C++ - 반복자 분류

from Study/C++ 2007/08/02 19:09 view 20634
  1. 형태별 분류
    1. 일반 포인터
    2. Container Iterator
    3. Stream Iterator
    4. Inserter Iterator

  2. 기능별 분류
     

    =*i

    *i=

    ++i

    i++

    --i

    i--

    i[n]

    i+n

    i-n

    i+=n

    i-=n

    입력 반복자

    O

     

    O

    O

                 

    출력 반복자

     

    O

    O

    O

                 

    정방향 반복자

    O

    O

    O

    O

                 

    양방향 반복자

    O

    O

    O

    O

    O

    O

             

    임의 접근 반복자

    O

    O

    O

    O

    O

    O

    O

    O

    O

    O

    O


  3. 5가지 종류로 구분하는 이유
    1. 알고리즘 함수가 요구하는 반복자에 따라 알고리즘 함수를 구분하기 위해서이다.
    2. 프로그램 ? Container ( 출력 )
    3. Container ? 프로그램 ( 입력 )

  4. Example
    1. find( first, last, value );    // 최소한 입력 반복자
    2. reverse( first, last );       // 최소한 양방향 반복자
    3. sort( first, last );            // 퀵소트라면 최소한 임의접근 반복자. 
                                        // 입.출력,정.양방향 은 내부에 sort 함수를 가지고 있다.
Tag |

// 1. 개념. 용어

반복자는(Iterator)는 포인터와 유사한 객체로서 STL의 알고리즘 함수가 컨테이너에 저장된 객체들의 시퀀스를 순회 할 때 사용한다. 컨테이너와 알고리즘 함수의 사이를 연결해주는 중간자로서의 역할을 담당하기도 한다. 반복자 덕택에 저장방식(자료구조)에 관계없이 동일한 알고리즘 함수를 구현 할 수 있는 것이다.

 

STL의 각 컨테이너는 자신의 요소를 가르키는 반복자를 가지고 있다. 각 컨테이너의 begin(), end() 함수는 자신이 지닌 첫번째 요소와 마지막 다음(past-the-end) 요소를 가르키는 반복자를 리턴한다.

 

반복자 구간 ? 시퀀스의 시작을 가르키는 first, 마지막 다음을 가르키는 last의 반복자 한 쌍. 반복자 구간은 [first, last] 처럼 표기한다. 또한, first에서 시작해서 operator++ 연산으로 도달 가능한 경우 유효(Valid, 도달가능-reachable)한 구간이라고 한다. 모든 STL의 알고리즘은 넘겨 받은 구간이 유효하다는 가정하에 작업을 수행한다. 또한 아무 요소도 없는 구간은

first == last

가 되는데 이를 빈 구간(empty)라고 한다. 빈 구간도 유효한 구간이다.

Past the end ? Container end() 함수를 통해서 얻게 되는 iterator는 마지막 요소가 아니라 마지막 다음을 가르키는데 이를 보통 past-the-iterator라고 부른다. iterator를 참조하는 것은 오류이다.

 

// 2. 반복자의무효화

void main()

{

           vector<int> v(10);

 

           v[0] = 100;

 

           vector<int>::iterator p = v.begin();

 

           cout << *p << endl;

 

//        v.resize(20); // 반복자를 무효화 시킨다.p 가리키는 곳을 재할당

           v.resize(5); // 무효화 될 가능성이 있다. 메모리를 줄이기만 한다.

 

           cout << *p << endl;

}

 

///////////////////////////////////////////////////////////////////

// 3. 반복자의 활용

void main()

{

           list<int> s;

 

           s.push_back(10);

           s.push_back(20);

           s.push_back(30);

           s.push_back(40);

 

           slist<int>::iterator p1 = s.begin();

           cout << *p1 << endl;

 

           slsit<int>::iterator p2 = s.end();

 

           reverse( p1, p2 )

}

 

///////////////////////////////////////////////////////////////////

void main()

{

        vector<list<int> > st(10); // hash table

 

        st[0].push_back(10);

 

        vector<string> v(10);

 

        v[0][0] = 'a';

 

        string s = "ahfsdhksdfkshdfkjhsdkfhsdkfh";

 

        sort(s.begin(), s.end());

 

        reverse( s.begin(), s.end());

 

        replace( s.begin(), s.end(), 'f', '-');

 

        cout << s << endl;

}

 

 

// 반복자의분류- 5가지

int main()

{

        list<int> s;   // 양방향반복자

 

        sort( s.begin(), s.end());    // 임의접근이어야한다.

        s.sort(); // Quick 이아닌버블이나selection 으로구현됨.

       

        int x[10] = { 1,2,3,4,5,6,7,8,9,10};

        int y[10];

 

        copy( x, x+10, y); // x ~ x+10y로복사한다.

 

        const int x[10] = { 1,2,3,4,5,6,7,8,9,10};

       

        int k = *x; // ok..

        *x = 20; // error

        slist<int> s;

 

        // s에요소추가...

        slist<int>::iterator p = s.begin();

 

        int k = *p; // 입력

        *p = 30;    // 출력

 

        ++p; // ok...

        --p; // 될까?? 안된다. single linked list는 전방향!!

}

 

Tag |

8.1(수) C++ - template 전문화

from Study/C++ 2007/08/02 18:05 view 22060

// template 전문화가 요즘들어 인기를 얻고 있는 이유. - 메타의 세계

// 컴파일시간에 어떤일을 수행하게 하는 기법. 컴파일시간은 오래 걸리지만

// 실행시간이 단축된다. 주로 전문화를 사용해서 컴파일 재귀호출을 사용한다.

// 하지만 컴파일 역량이 있기 때문에 9번이상?? 은 안된다. 왜그렇까..컴파일 하기 싫은가..


template
<int n> class Pow

{

public:

        enum { result = n * Pow<n-1>::result };

};

 

template<> class Pow<0>

{

public:

        enum { result = 1 };

};

 

void main()

{

        int n = Pow<5>::result;


       
cout << n << endl;

}

 

/////////////////////////////////////////////////////////////////

// Template 전문화( 특화, Specialization ).

template<typename T, typename T2> class Test {};     // 1

template<typename T> class Test<T, int> {};          // 2

 

Test<int, double> t1;  // 1

Test<int, int> t2;     // 2

 

// Primary Template

template<typename T> class Stack

{

        T* buf;

};

 

// 전문화 Template

template<> class Stack<int>

{

};

 

// 부분전문화- 모든 포인터는 이 클래스 사용

template<typename T> class Stack<T*>

{

        T* buf;

};

 

void main()

{

        Stack<int> s;

}

 

Tag |

8.1(수) C++ - typename

from Study/C++ 2007/08/02 17:17 view 21746

#include <iostream>

using namespace std;

 

// typename 문법이야기

// 1.2 의 중복문제가 발생해서 이를 해결하고자 typename 키워드를 만들었다.

// 그러고 보니 class T 라는 것의 의미가 명확하지가 않는 것을 알 수가 있었다.

// class Tint와 같은 타입도 받을 수 있기 때문에 typname으로 바뀌게 된 것이다.!!!

// 하지만 class는 여전히 지원된다.

 

template<typename T> void foo( T a )

{

        typename T::B* p;
        // 1. T
안에 내포클래스로 B가 있는데 그 포인터 p를 선언.

        // 2. T안에 B라는 static 변수가 있는데 곱하기 p를 한다.

}

 

class A

{

public:

        static int B;

 

        class B

        {

        };

};

 

void main()

{

        A a;

        foo( a );

}


//////////////////////////////////////////////////////////////////// 
// 디폴트 인자

template<typename T = int, int n = 10> class Stack

{

        T buf[n];

};

 

void main()

{

        Stack<int, 10> s;

        Stack<int> s2;

 

        stack<> s3;    // 모두 default 사용

}

Tag |

8.1(수) C++ - template 파라미터

from Study/C++ 2007/08/02 16:43 view 20862

#include <iostream>

#include <vector>

using namespace std;

 

// template 파라미터의종류

// 1. type

// 2. 상수( 정수와포인터상수만가능) 파라미터.

// 3. template temlpate 파라미터- template 이름을 넘긴다???

 

// vector는 디폴트 인자가3 개가 있으므로 넘기기 힘들다.

// 그래서 새롭게 만든 template를 넘겨보자!! VECTOR

template<typename T> class VECTOR

{

};


template
<template<typename> class A, typename T> class Stack

{

        A<T> v;

public:

};

 

int main()

{

        Stack<VECTOR, int> s;

 

        return 0;

}


//////////////////////////////////////////////////////////////////// 

template <typename T, int n, template<typename> class A> class Stack

{

        A<T> v;                // 결국 vector<int> v

        T buf[n];              // 배열첨자에 템플릿인자 상수는 가능하다.

};

 

void main()

{

        vector<int> a;

        vector b;

 

        Stack<int, 10, vector> s;

 

        int n = 10;

        //Stack<int, n> s2;    // error

}


//////////////////////////////////////////////////////////////////// 

// 클래스template 2 

typedef vector<vector<int> > Matrix;

 

void main()

{

        //vector<vector<int> > m(3, 3);

        Matrix m(3, 3);

       

        m[0][0] = 10;

       

        vector<int> v(10, 3);

 

        v[0] = 10;

}

 

//////////////////////////////////////////////////////////////////// 
template
<typename T> class Stack

{

};

void main()

{

        Stack<int> s;

        Stack<Stack<int> > s2; // >> 와 혼동 되지 않도록 해야 한다.

}

 

Tag |

// 클래스 template의 기본.
template
<typename T> class Stack

{

        T* buf;

public:

        Stack() {}             // 1. ok. 생성자이름은클래스이름

        //Stack<T>() {}        // 2. 에러

 

        // 복사생성자의모양

        Stack( const Stack<T>& ) {}

 

        void push ( T a );

};

 

// 클래스template의멤버함수를외부에구현하려면

template<typename T> void Stack<T>::push( T a )

{

}

 

void main()

{

        Stack<int> s1;

//      Stack      s2;  // error. Stack template의이름이지Type이아니다.

                        // typeStack<T> 이다.

}



// 멤버 함수 template를 활용해보자.!!! 

template<typename T> class Stack

{

public:

        Stack(){}

        template<typename U> explicit Stack(const Stack<U>&)

        {

        }

        explicit Stack(const Stack<T>&)

        {

        }

 

};

void main()

{

        Stack<int> s1;

        Stack<int> s2(s1);

 

        Stack<int> s3;

        Stack<double> s4(s3);

}

 

 

Tag |