alones.kr/blog로 사이트 이전했습니다. 관련 공지

Alones world : Location : Tag : GuestBooks : Admin : New Article : Alones Wiki : Joinc TeamBlog
Alones world 블로그에 오신것을 환영해요^^
gidaeyeo@gmail.com
175
238
353112

Add to Google Reader or Homepage

 Subscribe in a reader

현재 접속 자 수
hit counters
------------
Recently Popular Posts
------------
'STL'에 해당되는 글 15건

요즘은 list나 vector도 쓰지만 map도 즐겨 쓰는 편이다.

key와 value로 값을 정리하고 빠른 indexing을 위해서라면 STL의 컨터이너 중 map을 가장 먼저 생각해 볼 수 있을 것이다.

아무튼,
std::map의 각 member function들을 정리하기 이전에 전반적으로 map에 대해서 간략히 정리해보았다.

최신 내용은 아래 wiki에서 확인할 수 있다.

in my wiki: http://alones.byus.net/moniwiki/wiki.php/map?action=show


  • initial version: 2007.07.16

목차

1 std::map
2 iterator
3 key를 위한 class
4 예제 코드
5 Reference

1 std::map #


다른 STL의 컨테이너 처럼 map은 많은 장점을 가진 유익한 컨테이너이다.

두서 없지만 map의 특징에 대해서 간단히 살펴 보면 다음과 같다.

  • key와 value로 element를 관리할 수 있다.
  • key는 숫자 이외에도 문자열 순서를 가질 수 있는 (즉, 비교 연산자를 가지고 있는) 데이터 타입이면 모두 key가 될 수 있다.
  • key는 순서 (order)를 가지고 관리되기 때문에 검색이 빠르다.
  • key는 unique해야 한다.
  • aMapkey = value 와 같이 [] 연산자를 제공해준다.
  • Element가 추가/삭제 될 때 크기도 같이 확장 축소 된다.

2 iterator #

  • 양방향 iterator를 제공하고 다음과 같이 key와 value를 접근할 수 있다.


map<Key,T>::iterator it;
(*it).first; // the key value (of type Key)
(*it).second; // the mapped value (of type T)
(*it); // the "element value"
// (of type pair<const Key,T>)

// 다음과 같이 사용할 수도 있다.
it->first; // (*it).first (the key value)
it->second; // (*it).second (the mapped value)//

3 key를 위한 class #

위에서 언급했듯이 key는 숫자 이외에도 순서를 가진 데이터 타입이면 모두 가능하다. 즉, operator< 를 구현하고 있으면 된다. 하지만 여기서 주의할 것은 (VC++ 6.0의 경우)

map에서 사용하고 있는 binary_function의 less가 두 operand를 모두 const로 받고 있기 때문에 const 멤버 함수로 구현해주어야 한다.

// TEMPLATE STRUCT less
template<class _Ty>
struct less : binary_function<_Ty, _Ty, bool>
{
bool operator()(const _Ty& _X, const _Ty& _Y) const
{return (_X < _Y); }
};
//

즉, 아래와 같은 형식으로 구현해주어야 한다.


// map의 키가 되기 위해서는 아래와 같이
// operator<를 구현하고 있어야 한다.
class CMyKey
{
public:
std::string m_key;
// map의 키가 되기 위해서는 비교 연산자가 필요
// const member function으로 구현 필요
bool operator<(const CMyKey& other) const
{
return m_key.c_str()[0] < other.m_key.c_str()[0];
};
// constructor
CMyKey(const char* key){ m_key = key;};
};
//

4 예제 코드 #


간단한 예제 코드를 만들어 보았다. key가 숫자 인 것은 흔히 볼 수 있을 것 같아서 순서를 가지고 데이터 타입으로 구현을 해보았다 (약간 말이 되지 않지만 ^^;;)

std::string을 가지고 있는 CMyKey를 key로 했고 CMyKey를 멤버로 가지고 있는 std::string의 첫 글자를 비교해서 순서를 정한다. 값은 간단한 std::string이다.

예제는 다음과 같다.



#pragma warning(disable:4786)
#include <map>
#include <string>
#include <iostream>

// map의 키가 되기 위해서는 아래와
// 같이 operator<를 구현하고 있어야 한다.
class CMyKey
{
public:
std::string m_key;
// map의 키가 되기 위해서는 비교 연산자가 필요
// const member function으로 구현 필요
bool operator<(const CMyKey& other) const
{
return m_key.c_str()[0] < other.m_key.c_str()[0];
};
// constructor
CMyKey(const char* key){ m_key = key;};
};
void main()
{
// map 선언
std::map<CMyKey, std::string> myMap;
// map에 값 넣기
myMap[ CMyKey("a")] = "a_value";
myMap[ CMyKey("b")] = "b_value";
myMap[ CMyKey("c")] = "c_value";
// check the size
std::cout<<"the size of map is: "
<<myMap.size()<<std::endl;
// 찾기 CMyKey("b") 인 것을 찾기
std::map<CMyKey, std::string>::iterator it;
it = myMap.find( CMyKey("b"));
if( it == myMap.end())
{
std::cout<<"could not find"<<std::endl;
}
else
{
// 찾아서 it->second를 value를 찍어 봄
std::cout<<"find the element. value is: "
<<it->second<<std::endl;
}
// iterator를 이용한 삭제
myMap.erase(it);
// 삭제 확인
it = myMap.find( CMyKey("b"));
if( it == myMap.end())
std::cout<<"Right. element is removed"
<<std::endl;
else
std::cout<<"Wrong. element exits"<<std::endl;
// clear
myMap.clear();
// check the size
std::cout<<"the size of map after clear: "
<<myMap.size()<<std::endl;
}
//

5 Reference #


크리에이티브 커먼즈 라이센스
Creative Commons License
Trackback 0 : Comment 9
http://alones.byus.net/tt/trackback/721
From. hyunghunny 2007/07/20 16:42Delete / ModifyReply
가끔 생각날때 들려서 배우고 갑니다.
밤 늦게까지 일하시는데도 항상 새로운 무언가를 잘 정리하셔서 블로깅해주시니
저같은 눈팅족에게는 영광입니다. ㅎㅎㅎ - 형헌
BlogIcon alones 2007/07/26 08:43Delete / Modify
:) 저도 방문해주시고 눈팅해주셔서 영광입니다. ^^
From. BlogIcon girl died too much sunscreen 2008/05/23 04:18Delete / ModifyReply
너는 위치를차가운 만들었다!
From. BlogIcon huge tits movies 2008/05/23 04:45Delete / ModifyReply
우수한 디자인!!
From. BlogIcon leather car seat repair 2008/05/23 05:22Delete / ModifyReply
아주 유용한 정보!
From. BlogIcon jolene blalock nude pic 2008/05/24 00:14Delete / ModifyReply
중대하고 유용한 위치!
From. BlogIcon las mujeres mas bonitas 2008/05/24 00:24Delete / ModifyReply
정말 같지 않는 블로그!
From. BlogIcon gay bondage clips 2008/05/24 00:33Delete / ModifyReply
너는 위치를차가운 만들었다!
From. BlogIcon celebrity uk upskirt 2008/05/24 03:40Delete / ModifyReply
유용한 정보. 좋은 디자인.

  • initial version: 2007.06.16

목차

1 Introduction
2 Signature
3 Inside
4 Usgae
5 References
6 See Alos

1 Introduction #

STL의 container (vector, list, etc)의 각 element를 이용한 작업을 할 때 용이한 std::algorithm의 template function 이다.

물론 iterator를 이용해서 순회 하면서 element를 이용해서 작업을 할 수 도있겠지만 작업 내용이 모든 element에 대해서 동일 (e.g. 출력) 할 경우는 for_each를 쓰는 것이 좋을 것이다.

그리고 for_each는 아래 signature에서 볼 수 있듯이 작업을 수행하는 단항 연산 함수가 전달 받는 것은 element의 value (e.g. *_F)이기 때문에 element 자체를 변경하기는 힘들다.

※ STL contaitner의 각 elements에 대한 변경은 transform을 참고. transform은 변경해서 output container를 만든다.

2 Signature #


함수 원형은 다음과 같다.
template <class InputIterator, class Function>
   Function for_each (
             InputIterator first, InputIterator last,
             Function f);





//
  • first: <input> container의 첫 번째 iterator
  • last: <input> container의 마지막 iterator
    • 즉, first 부터 last까지에 대해서 작업을 수행한다.
  • f: <input> element에 대해 작업을 할 단항 함수 (unary function)으로 다음이 될 수 있다.
    • unary funcion
    • unary opeartor (i.e. operator()) 를 재정의한 class
    • unary operator를 재정의한 struct

header
  • #include <algorithm>

3 Inside #


실제 Visual C++ 6.0의 CRT library에 정의된 std::for_each는 다음과 같은 모습을 가지고 있다.

// TEMPLATE FUNCTION for_each
template<class _II, class _Fn> inline
    _Fn for_each(_II _F, _II _L, _Fn _Op)
    {for (; _F != _L; ++_F)
        _Op(*_F);
    return (_Op); }


설명한 것과 같이 단항 함수가 받는 것은 *_F로 element의 값을 받고 있다.

4 Usgae #


다음은 10,20,30의 int를 가지고 있는 vector를 function, class, struct의 unary function을 이용해서 출력하는 예제이다.

#include <iostream>
#include <algorithm>
#include <vector>

// function for for_each
// element를 받아서 출력
void MyPrintFn (int i)
{
    std::cout << " " << i;
}

// class for for_each
// element를 받아서 출력
class MyPrintClass
{
public:
    void operator() (int i)
    {
        std::cout<<" "<<i;
    };
};

// struct for for_each 
// element를 받아서 출력
struct MyStruct
{
    void operator() (int i)
    {
        std::cout<<" "<<i;
    };
}  tStruct;

int main()
{
    // vector for eample
    std::vector<int> myvector;
    myvector.push_back(10);
    myvector.push_back(20);
    myvector.push_back(30);

    // #1. function
    std::cout << "for_each by function"<<std::endl;
    std::for_each(myvector.begin(), myvector.end(), MyPrintFn);

    // #2. class
    std::cout << "\nfor_each by class "<<std::endl;
    MyPrintClass myPrintClass;
    std::for_each (myvector.begin(), myvector.end(), myPrintClass);

    // #3. struct
    std::cout << "\nfor_each by strcut "<<std::endl;
    std::for_each (myvector.begin(), myvector.end(), tStruct);

    std::cout<<std::endl;

    return 0;
}


//

출력 결과
for_each by function
 10 20 30
for_each by class
 10 20 30
for_each by strcut
 10 20 30
Press any key to continue

6 See Alos #





최신 내용은 아래 wiki에서 확인 할 수 있다.
 in my wiki: http://alones.byus.net/moniwiki/wiki.php/for_each?action=show




크리에이티브 커먼즈 라이센스
Creative Commons License
Trackback 1 : Comment 2
http://alones.byus.net/tt/trackback/676
From. cheap clopidogrel 2008/05/22 22:23Delete / Modify
cheap clopidogrel
Trackback
From. BlogIcon china 2008 olympic game 2008/05/23 04:29Delete / ModifyReply
뉴스를 위한 감사합니다…
From. BlogIcon female confirmation names 2008/05/23 04:56Delete / ModifyReply
걸출한 위치! 많은 감사.

  • initial version: 2007.06.15

목차

1 Introduction
2 Signature
3 Inside
4 Usgae
5 References
6 See Alos

1 Introduction #

STL의 Container (std::list, std::vector, etc)들의 모든 elements를 변환할 때 사용한다 (의미하는 그대로). algorithm에 포함된 것 답게 unary (단항) operator나 binary (이항) operator를 parameter로 받아서 처리해준다. 즉, std::vector의 모든 elements를 1씩 증가 시켜주거나 prefix로 특정 문자를 붙이는 경우 사용할 수 있을 것이다.

2 Signature #


다음과 같이 두 가지 원형을 제공한다.

template < class InputIterator, 
class OutputIterator, class UnaryOperator >
OutputIterator transform
( InputIterator first1, InputIterator last1,
OutputIterator result, UnaryOperator op ); template < class InputIterator1, class InputIterator2, class OutputIterator, class BinaryOperator > OutputIterator transform
( InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, OutputIterator result, BinaryOperator binary_op );
//

첫 번째 것은 단항 연산자를 이용해서 입력으로 들어오는 container의 처음과 끝 iterator를 처리해주고 결과를 output conatiner의 iterator에서 차례로 넣어 준다. 두 번째 것은 이항 연산자를 이용해서 첫 번째 container (first1 ~ last1)와 두 번째 container의 시작 (frist2) 부터를 처리해서 output containter의 iterator에 차례로 넣어 준다.

3 Inside #


Visual C++ 6.0은 위 두 개 원형을 다음과 같이 구현해두었다. 설명 그대로이다.

// TEMPLATE FUNCTION transform WITH UNARY OP
template<class _II, class _OI, class _Uop> inline
        _OI transform(_II _F, _II _L, _OI _X, _Uop _U)
        {for (; _F != _L; ++_F, ++_X)
                *_X = _U(*_F);
        return (_X); }
// TEMPLATE FUNCTION transform WITH BINARY OP
template<class _II1, class _II2, class _OI, class _Bop> inline
        _OI transform(_II1 _F1, _II1 _L1, _II2 _F2, _OI _X,
_Bop _B)
{for (; _F1 != _L1; ++_F1, ++_F2, ++_X) *_X = _B(*_F1, *_F2); return (_X); }
//

4 Usgae #

다음의 간단한 예는 10,20,30,40,50이 elements로 들어있는 vector를 unary operator를 이용해서 1씩 증가시키고 binary operator를 이용해서 최초 vector와 1씩 증가한 vector를 더하는 예이다.

#include <iostream>
#include <algorithm>
#include <vector>

// 1씩 증가 시키는 unary operator
int op_increase (int i)
{
        return ++i;
}

// 두 수를 더하는 binary operator
int op_sum (int i, int j)
{
        return i+j;
}

int main ()
{
  std::vector<int> first;
  std::vector<int> second;
  std::vector<int>::iterator it;

  // 첫 번째 container
  // 10, 20, 30, 40, 50
  for (int i=1; i<6; i++)
          first.push_back (i*10);

  // 두 번째 container size 할당
  second.resize(first.size());

  // usage 1
  // 첫 번째 container의 elements를 
  // op_increase unary operator를 이용해서 
  // 1씩 증가
  // 결과 11, 21, 31, 41, 51
  std::transform (first.begin(), first.end(),
                                  second.begin(),
                                  op_increase);

  // usage 2
  // 첫 번째 container의 elements와
  // usgae 1의 결과 container를
  // op_sum인 binary operator를 이용해서 
  // 더함
  // 결과 21, 41, 61, 81, 101
  std::transform (first.begin(), first.end(),
                              second.begin(),
                              first.begin(),
                              op_sum);

  // 결과 출력
  std:: cout << "first contains:";
  for (it=first.begin(); it!=first.end(); ++it)
    std::cout << " " << *it;

  std::cout << std::endl;
  return 0;
}

//


6 See Alos #



※ 최신 내용은 아래 wiki에서 확인할 수 있습니다.
 in my wiki: http://alones.byus.net/moniwiki/wiki.php/transform?action=show

크리에이티브 커먼즈 라이센스