출처 카페 > C언어를 배우자 | 라온
원문 http://cafe.naver.com/cafec/505
말이 좀 어려운 것 같은데 그냥 훑어 보세요. 프로그램 해 보면 차츰 익숙해 질겁니다.

예제를 만들어 하나씩 살펴보고 직접 해보시면 꽤 간단하게 프로그램이 만들어 지는 것을 경험 하실 겁니다. 우선 STL에 대해 살펴 보겠습니다.

STL에는 6가지의 주요 component가 있습니다.

1. container : data set 이라고 생각하시면 쉽게 이해 됩니다.

2. generic algorithm : <algorithm> 과 container 자체에 있는 Algorithm 입니다.

3. iterator : C/C++의 포인터와 같이 Conatiner의 요소를 지정할 수 있는 객체입니다.

container를 잘 사용할려면 반드시 알아야 합니다.

보통 서적에서는 반복자라는 말을 쓰던데 특성을 보고 이름을 그리 붙인것 같습니다.

4. function object : accumlate 같은 것인데 그리 범용이라고 보기는 힘들지만..

5. adaptor : component의 interface를 변경하는 component입니다.

6. allocator : 할당기라고 하는데요. STL container는 allocator class를 사용하여 프로그램에서

사용하고 있는 메모리 할당 관련 정보를 캡슐화 하고 있습니다.

우선 Container를 보구요 다른 내용은 예제로 자세히 보는 것이 좋을 것 같습니다.

아래 내용은 STL Tutorial and Reference Guide 2nd 내용입니다.

Container

객체들의 컬렉션을 저장하고 있는 객체를 STL에서는 컨테이너라고 합니다.

두가지 종류가 있는데 Sequence Container , Sorted Associative Container 입니다.

Sequence Container : 타입이 동일한 객체들을 선형으로 구성한 컬렉션

- vector<T> : 가변길이 시퀀스를 임의 접근 할 수 있으며, 시퀀스 맨 끝에서 수행되는 삽입과

삭제는 아모타이즈드 상수 시간에 수행이 가능합니다.

참고 : 임의접근(random access)이 가능하다는 것은 시퀀스 i 번째 원소를 접근하는데 걸리

는 시간이 상수 시간이라는 것을 의미합니다. 이는 몇 번째이건 관계없이 항상 일정 하다는

것입니다.

- deque<T> : 가변길이 시퀀스를 임의 접근 할 수 있으며 시퀀스 맨 앞과 맨 끝에서 수행되는

삽입과 삭제는 모두 아모타이즈드 상수 시간에 수행이 가능합니다.

- list<T> : 가변길이 시퀀스에 대해서 선형 시간 접근만이 가능하며, 삽입과 삭제는 시퀀스 내

에서라면 어디서든지 상수 시간 내에 수행이 가능합니다.

Sorted Associative Container : 주어진 키로 컬렉션에서 객체를 신속하게 찾을 수 있는

기능을 제공합니다. 컬렉션의 사이즈는 실행시에 변할 수 있고 네 가지 타입이 있습니다.

- set<Key> : 유일키를 지원하며, 원하는 키를 신속하게 찾아 냅니다.

- multiset<Key> : 중복키를 지원하며, 원하는 키를 신속하게 찾아 냅니다.

- map<Key, T> : 유일키를 지원하며, 주어진 키로 원하는 객체를 신속하게 찾아 냅니다.

- multimap<Key, T> : 중복키를 지원하며, 주어진 키로 원하는 객체를 신속하게 찾아 냅니다.


STL Component

 

STL Container Types

출처 카페 > C++ Standard Te.. | 라온
원문 http://cafe.naver.com/cppstl/570

Singleton pattern을 이용하여 Config 파일을 이용하는 예 입니다.

Config는 여러 Application에서 사용할 수 있는 것이기 때문에 Singleton 형태로 한 번만 init하여

전체 공통으로 사용하도록 하고, 실제 프로그램 구성하여 사용 할 때는

System Environment(unix의 경우 getenv ) 설정으로 사용할 수 있습니다.

data container는 map을 이용하고 있으며, key, value 모두 string 입니다.

아래 예에서 사용한 Config.txt 내용은

#--------------------------------------------------------------------
# File Name : config.txt
# Author Name : Jeong il Ahn
# Description : Config file
# version : 1.0
# last edit : 200 . .
#---------------------------------------------------------------------
# Directory Information
#---------------------------------------------------------------------
DEFDIR=TESTDIR
#---------------------------------------------------------------------
# File Information
#---------------------------------------------------------------------
# End of File
EOF=[EOF]
# End of String
EOS=[EOS]
#---------------------------------------------------------------------

이런 형태이며, #은 주석으로 사용합니다.

key=value 형태로 구성되어 있습니다.

예제 main과 Config Source는 다음과 같습니다.

main.cpp

1 /*------------------------------------------------------------------------------------
2 * finename : main.cpp
3 * eng'r name : Jeong-il Ahn(raon_pgm@naver.com)
4 * date : 200 . 00. 00.
5 * title : This source is config for to test
6 *-----------------------------------------------------------------------------------*/
7
8 #include <iostream>
9 #include "config.h"
10
11 int main(int argc, char *argv[])
12 {
13 // config value initialize
14 if( !Config::instance()->init() ){
15 std::cerr << "System failed to initialize config!!!" << std::endl;
16 std::exit(EXIT_FAILURE);
17 }
18
19 std::cout << "End Of File is : ";
20 std::cout << Config::instance()->getCfgValue("EOF") << std::endl;
21
22 std::cout << "System Default Directory : ";
23 std::cout << Config::instance()->getCfgValue("DEFDIR") << std::endl;
24
25 }

config.h

1 #ifndef __CONFIG_H__
2 #define __CONFIG_H__
3
4 #include <map>
5 #include <string>
6 #include <fstream>
7
8 //! default config file declaration
9 static std::string DEFAULT_CONFIG = "config.txt";
10 //! configuration class
11 /*!
12 Programmer : Jeong-il Ahn(raon_pgm@naver.com) \n
13 date : 2001. 05. 14.\n
14 title : system config value define header\n
15 purpose : config value initialize from config.txt into map container\n
16 */
17 class Config{
18 public:
19 //! key/value container Map_STRSTR declaration. key : string, value : string
20 typedef std::map<std::string, std::string> Map_STRSTR;
21 //! config file load in mapConfigValue_
22 bool init();
23 //! singleton pattern - instance() function declaration
24 static Config* Config::instance();
25 //! mapConfigValue_에서 입력된 string으로 key 검색
26 /*!
27 \param key config내에서 찾고자 하는 key string
28 \return map container에서 key에 해당하는 value
29 */
30 std::string getCfgValue( std::string key )
31 {
32 return mapConfigValue_[key];
33 }
34
35 private:
36 //! static config point
37 static Config* the_config;
38 //! config file stream에서 memory로 데이터를 읽어 들인다.
39 /*!
40 \param *ifstr config file stream pointer
41 \return 파일 처리가 정상적으로 완료 되었을일 경우 true 이상이 있을 경우 false
42 */
43 bool readCfgIntoMemory ( std::ifstream &ifs );
44 //! map< string, string > type data container
45 Map_STRSTR mapConfigValue_;
46 };
47
48 #endif //!__CONFIG_H__

config.cpp

1 /*------------------------------------------------------------------------------------
2 * finename : config.cpp
3 * eng'r name : Jeong-il Ahn(raon_pgm@naver.com)
4 * date : 2001. 05. 14.
5 * title : system config value define source
6 * purpose : config value initialize from ./config/config.txt into map container
7 * description : using the singleton design pattern
8 *-----------------------------------------------------------------------------------*/
9
10 #include <iostream>
11 #include <fstream>
12 #include <cstdio>
13 #include <cstdlib>
14 #include <string>
15 #include <sys/types.h>
16
17 #include "config.h"
18
19 Config* Config::the_config = 0;
20
21 Config* Config::instance()
22 {
23 if( !the_config ){
24 the_config = new Config();
25 }
26 return the_config;
27 }
28
29 bool Config::init()
30 {
31 std::ifstream cfgFile( DEFAULT_CONFIG.c_str() );
32 if( ( !cfgFile ) || ( cfgFile.fail() ) ){
33 std::cerr << "Can't open file " << DEFAULT_CONFIG << std::endl;
34 return false;
35 }
36
37 if( !readCfgIntoMemory( cfgFile ) ) return false;
38
39 return true;
40 }
41
42 bool Config::readCfgIntoMemory( std::ifstream &ifs )
43 {
44 std::string oneLine;
45
46 while( !ifs.eof() ){
47 std::getline( ifs, oneLine );
48 if( oneLine == "" || oneLine[0] == '#' )
49 continue;
50 else{
51 size_t idx = oneLine.find( "=" );
52 if( idx == std::string::npos ){
53 std::cout << "Line = " << oneLine << std::endl;
54 std::cout << "Define failure line in config.txt" << std::endl;
55 continue;
56 }
57
58 std::string key, value;
59 key = value = oneLine;
60 key.erase( idx );
61 value.erase( 0, idx+1 );
62
63 mapConfigValue_[key] = value;
64 }
65 }
66 return true;
67 }

  • Vector

- 벡터

  1. 대용량의 데이터를 효과적으로 다룰 수 있는 클래스
  2. 용량 변경이 용의
  3. 벡터에 저장하는 모든 데이터는 Object타입
  4. 어떤 종류의 객체도 함께 담을 수 있다.

- 벡터 생성자

  1. vector : 초기용량이 10, 용량 초과시 크기를 두배 씩 증가
  2. vector(int a) : 지정한 크기의 용량으로 초기화된 Vector 객체를 생성
  3. vector(int a, int b) : 지정한 크기의 용량으로 초기화된 벡터 객체를 생성하고 용량 초과시 b 만큼 증가

- 벡터에 객체 저장

  1. void add(int index, Object object) : 지정한 인덱스의 위치에 객체를 추가
  2. void addElement(Object object) : 벡터의 끝에 객체를 추가

- 벡터 부터 객체 삭제

  1. Object remove(int index) : 지정한 위치의 객체를 벡터에서 제거
  2. boolean remove(Object object) : 지정한 객체를 벡터에서 제거
  3. void clear() : 벡터의 모든 요소를 제거

- 벡터로부터 객체 검색

  1. Object elementAt(int index) : 지정한 위치의 객체를 리턴
  2. Object get(int index) : 지정한 위치의 객체를 리턴

- 벡터의 기타 메소드

  1. int capcity() : 벡터의 현재 용량의 리턴
  2. boolean contains(Object object) : 주어진 요소가 벡터에 있는지 알아봄
  3. int indexof(Object object) : 주어진 요소의 위치를 리턴(없으면 -1)
  4. int size() : 벡터에 포함되어 이쓴 요소의 수를 리턴
  5. void trimToSize() : 벡터의 용량을 현재 벡터의 크기에 맞게 수정

- Enumeration : 벡터에 저장된 객체를 열거형으로 리턴

Enumeration e = v.elemetns();

while(e.hasMoreElements()) {

System.out.println(e.nextElement());

}

- Iterator : Collection에 저장된 객체를 나열 또는 열거하기 위한 인터페이스

Iterator ie = v.iterator();

while(ie.hasNext()) {

System.out.println(ie.next);

}

  • List 인터페이스

- 컬렉션 가운데 List가 갖는 가장 큰 특징은 List가 갖고 있는 객체의 순서가 있다

- List가 가지고 있는 객체마다 순서번호(인덱스)를가지고 있다

- 리스트가 갖고 있는 몇 번째 객체를 직접 참조 가능

- 리스트에 객체를 추가할때 원하는 위치에 추가도 가능

List

Object get(int index) List의 index번째 객체를 꺼냅니다.

int indexOf(Object o) List에 객체 o가 나타나는 첫번째 인덱스

(List에 객체 o가 없다면 - 1)

int lastIndexOf(Object o) List에 객체 o가 나타나는 마지막 인덱스

(List에 객체 o가 없다면 - 1)

ListIterator listIterator() List의 ListIterator

ListIterator listIterator(int index) List의 index부터 시작한 ListIterator

Object set(int index, Object o) List의 index번째에 객체를 객체 o로 바꿉니다.

index번째에 있었던 이전 객체 List subList(int from,int to)

(List의 from번째부터 to번째까지 객체를 List로 리턴)







----------------------------------------------------------------------------------------------


list와 vector중
list는 중간 삽입 및 삭제가 개체 수가 클수록 유리하지만,

저장하는 데이터의 개수가 적고 랜덤 접근을 하고싶을 경우엔 오히려 vector가 유리함


  vector list
크기 변경 가능 O O
중간 삽입 및 삭제가 용이 X O
순차 접근 가능 O O
랜덤(임의) 접근 가능 O X


대부분의 방만들어서 플레이어끼리 겜하는 게임들은 방에 들어온 플레이어들 관리할때 이방식으로 많이 씀
방만들었을때 그방안에 플레이어가 왔다갔다 자주 하지만 그 수가 작아 미치는 영향이 없다 함