글 목록 보기

Lyn
조회 수 41224 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

이번엔 lexical_cast 에 대해서 알아보자.
cast 란 이름에서 눈치챗겠지만 일종의 캐스팅 연산자(인 척 하는 함수) 이다.
string -> Integer 같은 상식적으론 말이 되지만 C++문법상으론 말이 안되는 일들을 처리한다.

일단 예제코드를 소개한다.
timer 에 관해서는
http://lunapiece.net/3795 를 참조해라

#include <boost/lexical_cast.hpp>

#include <cstdlib>

#include <string>

#include <boost/timer.hpp>

 

using namespace std;

using namespace boost;

 

string Number = "1024768";

 

void StrToIntAtoi()

{

        int num;

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

        {

               num = atoi(Number.c_str());

        }

        printf("atoi : %d\n", num);

}

void StrToIntStringStream()

{

        stringstream sst;

        int Num;

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

        {

               sst << Number.c_str();

               sst >> Num;

        }

        printf("StringStream : %d\n", Num);

}

void StrToIntLexicalCast()

{

        int num;

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

        {

               num = lexical_cast<int>(Number);

        }

        printf("LexicalCast : %d\n", num);

}

int _tmain(int argc, _TCHAR* argv[])

{

        timer t;

        printf("atoi 를이용한방법\n");

        t.restart();

        StrToIntAtoi();

        printf("%lf \n", t.elapsed());

 

        printf("StringStream 을이용한방법\n");

        t.restart();

        StrToIntStringStream();

        printf("%lf \n", t.elapsed());

 

        printf("lexical_cast 를이용한방법\n");

        t.restart();

        StrToIntLexicalCast();

        printf("%lf \n", t.elapsed());

 

        return 0;

}

 

.....

예제코드 자체는 별 문제가 없었으리라 본다. 준비작업도 필요없고 간단하게 쓸 수 있어서 참 좋아보이기는 한다.
하나의 함수로 이런저런 캐스팅을  다 할수 있으니 다형성도 뛰어나다.
그러나 치명적인 문제가 딱 하나 있는데...

 

 

바로 이거다 속도 =_=;

stringstream 에 비해 약 10배, atoi 에 비해선 대략 50배 가량 느리다 =_=;; 편의성을 위해서 가끔 쓰는정도라면 몰라도 자주 반복되는 루틴에서는 쓰지 않아야 하겠다.

?

Lyn
조회 수 36537 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

multi_array는 다차원 정적배열을 지원하는 클래스이다.
이를 이용하는 다른 방법은 std::tr1::array 를 중첩해서 사용 하는 방법이 있는데, 이것을 좀 더 편하게 확장했다고 보면 되겠다.

std::tr::array에 관한 내용은 아래 링크를 참조해라
http://lunapiece.net/Article/476

 

아래는 multi_array와 중첩된 array에 관한 예제코드이다. 이것도 별 내용이 없다보니 그냥 코드 보여주는걸로 끝낸다.

 

#include "stdafx.h"

#include <array>

#include <multi_array.hpp>

#include <cstdio>

 

using namespace boost;

 

int _tmain(int argc, _TCHAR* argv[])

{

        //TR1Array를이용한Static Array of Array 구현

        printf("std::tr1::array<std::tr1::array<int,20>, 10>\n");

        std::tr1::array<std::tr1::array<int,20>, 10> Stdarr; //int[10][20] 선언

        //10*20인데선언시에는숫자가반대로씌여지므로헤깔린다!

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

        {

               for(int j = 0;j < 20; ++j)

               {

                       Stdarr[i][j] = 1;

               }

        }

 

        //boost::multi_array

        printf("multi_array 사용\n");

        multi_array<int, 2> MultiArray(extents[10][20]);

        //int2차원배열[10][20]을선언. 템플릿인자가Type 과차원을나타냄.

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

        {

               for(int j = 0;j < 20; ++j)

               {

                       MultiArray[i][j] = 2;

               }

        }

       

        printf("multi_array range 조정\n");

        //Pascal 처럼배열의인덱스를변형할수있는기능을제공한다.

        typedef multi_array<int, 2>::extent_range range; //이름이너무길어서ㅡ.

        multi_array<int, 2> MultiArray2(extents[range(1,4)][range(20,40)]);

        //Pascal 과비교하면Array [1..4-1] of Array[20..40-1] of Integer 라고할수있겠다.

        for (int i = 1; i < 4 ; ++i)

        {

               for(int j = 20;j < 40; ++j)

               {

                       MultiArray2[i][j] = 2;

               }

        }

        return 0;

}

 

 

 

?

Lyn
조회 수 43990 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

이번에는 timer 클래스이다.
단순히 시간을 재는데 이용 할 수 있는 클래스로 알고리즘 돌려놓고 시간측정하기 딱좋다.
아래 pool 예제 등에서도 이 timer 를 사용햇으면 더 편햇을텐데... 어쩌다 보니 이게 뒤로나왔다.

#include "boost/timer.hpp"

#include <cstdio>

#include <windows.h>

 

using namespace boost;

 

int main(int argc, char **argv)

{

        timer t; //생성시0으로초기화

        Sleep(1234);

        printf("%lf 초지남\n", t.elapsed());

        Sleep(1766);

        printf("%lf 초지남\n", t.elapsed());

        t.restart();//Restart 를이용하여다시초기화

        Sleep(512);

        printf("%lf 초지남\n", t.elapsed());

        return 0;

}

 

?

2009.05.11 22:44

[Boost 살펴보기] 2. any

Lyn
조회 수 36486 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

any 는 마치 스크립트 언어처럼 임의의 type을 가지는 변수를 만들 수 있다.
COM의 Varient 와도 비슷하다 하겠다.

하지만 이것을 언어수준에서 구현 해 놓았고, 다른 컨테이너와 매우 잘 맞물린다는것이 장점이라 하겠다.
vector 에 이런저런 잡데이터 쑤셔넣을때 참 좋더라
(당연히 오버헤드는 있다. 꼭 필요한 곳에만 사용하자!)

#include "stdafx.h"
#include <cstring>
#include <cstdio>
#include <boost/any.hpp>
#include <string>
#include <vector> 

using namespace boost;

using namespace std;

 

struct MyData

{

        int i;

        double d;

        MyData()

        {

        }

        MyData(const MyData& t) //Any의요구사항1 Copy Constructor

        {

               this->i = t.i;

               this->d = t.d;

        }

        MyData& operator =(const MyData &t) //Any의요구사항2 = operator overloading

        {

               this->i = t.i;

               this->d = t.d;

        }

};

int _tmain(int argc, _TCHAR* argv[])

{

        any Data;

        //값이비어있는지를확인하는방법

        if(Data.empty())

        {

               puts("Data 는비어있음!");

        }

        else

        {

               puts("Data 는비어있지않음!");

        }

        Data = 3.14; //실수리터럴의기본타잎은double

        Data = 3; //정수리터럴의기본타잎은Int

 

        //Data = "Hello!"; //에러.

        //any 에넣기위해선CopyConstructor = Operator Overloading 이필요하다.

        string str = "Hello";

        Data = str; //정상적

 

        //Any 에어떤타잎이들어있는지확인

        //type매소드로type 을확인후any_cast 연산자를사용하여캐스팅

        if(Data.type() == typeid(int))

        {

               printf("DataType : Int, Value : %d\n", any_cast<int>(Data));

        }

        else if(Data.type() == typeid(double))

        {

               printf("DataType : Double, Value : %lf\n", any_cast<double>(Data));

        }

        else if(Data.type() == typeid(string))

        {

               printf("DataType : string, Value : %s\n", any_cast<string>(Data).c_str());

        }

 

        //Vector Any 의복합사용예.

        printf("임의의타잎을담는Vector 선언하기\n");

        vector<any> AnyVector;

        MyData myData;

        myData.d = 5.12;

        myData.i = 5;

 

        AnyVector.push_back(3);

        AnyVector.push_back(3.14);

        AnyVector.push_back(myData);

 

        vector<any>::iterator it;

        for (it = AnyVector.begin(); it != AnyVector.end(); ++it)

        {

               if(it->type() == typeid(int))

               {

                       printf("Any Type : Int, Value : %d\n", any_cast<int>(*it));

               }

               else if(it->type() == typeid(double))

               {

                       printf("Any Type : Double, : %lf\n", any_cast<double>(*it));

               }

               else if(it->type() == typeid(MyData))

               {

                       printf("Any Type : MyData, Value : %d, %lf\n", any_cast<MyData>(*it).i, any_cast<MyData>(*it).d);

               }

        }

        return 0;

}

 

 

?

2009.05.11 22:04

[Boost 살펴보기] 1. pool

Lyn
조회 수 36885 추천 수 0 댓글 0
Atachment
첨부 '1'
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

TR1에 포함되지 않은 Boost 의 다른 요소들 중 자주 쓸 만한 것들을 한번 눈여겨 볼까 한다

첫번째 예제는 Pool이다. 메모리를 미리 생성 해 놨다가 해제/생성이 반복 될 경우 미리 생성해 놓은 메모리를 재활용 하는데 유용하게 사용 할 수 있다. 개인적으로도 많이 구현해서 써 보았고 탁월한 메모리 성능을 보여 주는 방법이다.

아래에는 예제코드를 담았다. 예제코드에 있는 주석만으로도 충분히 사용 방법과 기능을 알 수 있을것이라 본다.
그림은 아래 코드를 실행한 속도 테스트 스크린샷이다(VS2008 Sp1 + Realese Mode)
일반적으로 메모리를 할당하는것 보다 훨신 빠름을 알 수 있다. 게다가 단편화의 문제도 적다.

#include "stdafx.h"

#include <iostream>

#include <cstring>

#include <boost/pool/pool.hpp>

#include <boost/pool/object_pool.hpp>

#include <windows.h>

 

using namespace std;

using namespace boost;

 

struct MyData

{

        int i;

 

        MyData()

        {

               puts("Constructor!");

        };

        ~MyData()

        {

               puts("Destructor!");

        }

};

struct MyData2

{

        int i;

};

 

MyData2** Array; //임시저장용

 

void UseNormalPool()

{

        pool<> pool(sizeof(MyData));

 

        MyData *p = (MyData*)pool.malloc();      

        //pool.free(p); //Free를하지않을경우pool이파괴될때pool에서생성한모든메모리가파괴됨.

}

 

void UseObjectPool()

{

        object_pool<MyData> pool;

 

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

        {

               MyData *p = pool.malloc();

               //기본적으로같지만파괴시Destructor 가호출됨(주의: Constructor 는호출되지않음)

        }

}

void Test1NewAndDelete()

{

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

        {

               MyData2* p = new MyData2;

               delete p;

        }

}

void Test1MallocAndFree()

{

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

        {

               MyData2* p = (MyData2*)malloc(sizeof(MyData2));

               free(p);

        }

}

void Test1BoostPool()

{

        pool<> pool(sizeof(MyData));

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

        {

               MyData *p = (MyData*)pool.malloc();  

               pool.free(p);

        }

}

void Test2NewAndDelete()

{

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

        {

               Array[i] = new MyData2;

        }

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

        {

               delete Array[i];

        }

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

        {

               Array[i] = new MyData2;

        }

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

        {

               delete Array[i];

        }

}

void Test2MallocAndFree()

{

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

        {

               Array[i] = (MyData2*)malloc(sizeof(MyData2));

        }

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

        {

               free(Array[i]);

        }

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

        {

               Array[i] = (MyData2*)malloc(sizeof(MyData2));

        }

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

        {

               free(Array[i]);

        }

}

void Test2BoostPool()

{

        pool<> pool(sizeof(MyData2));

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

        {

               Array[i] = (MyData2*)pool.malloc();  

        }

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

        { 

               pool.free(Array[i]);

        }

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

        {

               Array[i] = (MyData2*)pool.malloc();  

               //Free후재할당을할경우이미생성된메모리가재사용됨

               //Free를하더라도실제메모리는파괴되지않음

        }

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

        { 

               pool.free(Array[i]);

        }

}

int _tmain(int argc, _TCHAR* argv[])

{

        UseObjectPool();

        UseNormalPool();

       

        Array = new MyData2*[1000000];

        int TickCount;

 

        puts("Alloc and Free 1000000 count");

        TickCount = GetTickCount();

        Test1NewAndDelete();

        printf("new And delete : %dms\n", GetTickCount() - TickCount);

 

        TickCount = GetTickCount();

        Test1MallocAndFree();

        printf("malloc And Free : %dms\n", GetTickCount() - TickCount);

 

        TickCount = GetTickCount();

        Test1BoostPool();

        printf("boost pool : %dms\n", GetTickCount() - TickCount);

 

        puts("Alloc 1000000 count and Free 1000000 count");

 

        TickCount = GetTickCount();

        Test2NewAndDelete();

        printf("new And delete : %dms\n", GetTickCount() - TickCount);

 

        TickCount = GetTickCount();

        Test2MallocAndFree();

        printf("malloc And Free : %dms\n", GetTickCount() - TickCount);

 

        TickCount = GetTickCount();

        Test2BoostPool();

        printf("boost pool : %dms\n", GetTickCount() - TickCount);

        return 0;

}

 

?

Lyn
조회 수 15485 추천 수 0 댓글 2

"비밀글입니다."


Lyn
조회 수 36520 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
아래코드는 C++ Builder 2009에서 테스트되었습니다.

//---------------------------------------------------------------------------

#include <vcl.h>
#include <vector>
#include <memory>
#include <iostream>
#include <cstdlib>
#pragma hdrstop

#include <tchar.h>

using namespace std;
using namespace std::tr1;

class Test
{
public:
    int i;
    Test()
    {
        cout << "Test is Create!" << endl;
    }
    Test(const Test& )
    {
        cout << "Test's Copy Constructor!" << endl;
    }
    ~Test()
    {
        cout << "Test is Destroy!" << endl;
    }
};
using namespace std;

//---------------------------------------------------------------------------

#pragma argsused
int _tmain(int argc, _TCHAR* argv[])
{
    cout << "스택에 1개 생성" <<endl;
    Test t1; // 생성 되고, 함수가 끝날때 파괴 될 것

    cout << "힙에 1개 생성" <<endl;
    Test* t2 = new Test; //생성
    cout << "힙에서 1개 파괴" <<endl;
    delete t2; //파괴

    cout << "스택에 10개 생성" <<endl;
    Test t3[10];
    vector<Test> v1;

    cout << "복사생성자가 작동한다" <<endl;
    for(int i=0;i<10;++i)
    {
        v1.push_back(t3[i]);
        //이렇게 하면 Copy Contructor 가 작동하므로 오버헤드가 큼
        //게다가 반드시 동적으로 할당해야 하는 VCL 객체에는 사용이 불가능
    }

    cout << "힙에 10개 생성 후 Vector에 넣는다" << endl;
    vector<Test*> v2;
    for(int i=0;i<10;++i)
    {
        Test* tt = new Test;
        v2.push_back(tt);
        //이렇게 하면 동적으로 할당할 수 있음.
        //그러나 vector 를 파괴하기 전에 일일히 루프를 돌면서 delete 해줘야함
        //vetror가 파괴될때 내장하고 있는 모든 객체를 파괴할 수는 없을까?
        //VCL 에서는 TObjectList 클래스를 제공한다! 그러나 이는 C++ 표준이 아니다.
        //게다가 Templete Class 가 아니라 Casting 을 추가로 해줘야 한다는 부담도있다
    }
    cout << "Vector 에 있는 10개를 파괴" << endl;
    for(int i = 10 - 1;i >= 0;--i)
    {
        delete v2[i];
    }

    cout << "shared_ptr 을 이용하여 넣는다" << endl;
    vector<shared_ptr<Test> > v3;
    for(int i=0;i<10;++i)
    {
        shared_ptr<Test> spt(new Test);
        v3.push_back(spt);
    //vector 인 v3 역시 Main이 끝나야 파괴됨.
    //v3이  파괴되기 전 shared_ptr 의 효과에 의해 v3 이 가지고있던 Test가 모두 파괴
    }

    cout << "벡터 자체를 동적으로 생성해서 테스트 해 보자" << endl;
    vector<shared_ptr<Test> > *v4 = new vector<shared_ptr<Test> >;
    for(int i=0;i<10;++i)
    {
        shared_ptr<Test> spt(new Test);
        v4->push_back(spt);
    }
    cout << "벡터를 박살내면 가지고 있던 Test 10개도 다 박살난다" << endl;
    delete v4;

    system("pause"); //이게 끝나야 Main 이 끝나므로 t1은 이 뒤에 파괴
    //vector 인 v3 역시 Main이 끝나야 파괴됨.
    //v3이  파괴되기 전 shared_ptr 의 효과에 의해 v3 이 가지고있던 Test가 모두 파괴
}
//---------------------------------------------------------------------------

/*
Ps. CopyConstructor 가 10번이 아닌 그 이상 실행 되는데.. 그 이유는 Vector 가 공간이 부족해서 재할당을 하면서 다시 복사생성자가 호출되기 때문입니다. 생각보다 오버헤드가 많이큽니다.
*/
?

Lyn
조회 수 35421 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
STL 에서는 B-Tree 기반의 Collection 이 준비되어 있는데, set ,multiset ,map ,multimap 의 4 종류이다.

그에 반헤 TR1에서는 위의 4종류의 Collection 에 대응되는 Hash 기반의 Collection 을 제공한다.
이름하여 unordered 시리즈(unordered_set, unordered_multiset, unordered_map, unordered_multimap) 이다. (이름너무 길다)

기본적인 사용법은 STL 의 콜렉션과 완전히 같으니 그냥 무시하도록 하겠다.

제일 기본적인 unordered_set 에 대해서만 예제를 보자

#include <iostream>
#include <string>
#include <unordered_set>

using namespace std;
using namespace std::tr1;

int main()
{
    unordered_set<string> UnOrderSet;

    UnOrderSet.rehash(10); //버켓의 갯수를 정의한다.
    //UnOrderSet.insert("김호광");
    UnOrderSet.insert("남병철");
    UnOrderSet.insert("류종택");
    UnOrderSet.insert("린");
    UnOrderSet.insert("박지훈");

    if(UnOrderSet.find("김호광") != UnOrderSet.end())
    {
        cout << "김호광 님은 볼랜드 포럼 회원입니다." << endl;
    }
    else
    {
        cout << "김호광 님은 볼랜드 포럼 회원이 아닙니다." << endl;
    }
}

위에말한대로 기본적인 사용법은 set 과 완전히 동일하다.
중요한 것은 rehash 매소드.  버켓의 갯수가 너무 많으면 메모리 낭비가 극심해지고, 너무 작으면 성능이 나빠집니다. 이래저래 귀찮은 Collection 이라 할 수 있겠군요





기본적으로 unordered_set 은 4개의 템플릿 인수를 받아드립니다.

Value(사용할 Type),  Hash(Value 를 Hash화 하는 함수객체), Pred(비교함수객체), Alloc(할당자)의 순서인데
Hash, Pred, Alloc 은 디폴트 파라미터가 있으므로 사용 하지 않아도 무방하다.

만약 기본적으로 C++에서 제공하는 놈(int, string, double 등등...) 들이 아닌 다른놈들을 사용하려면?
2가지 구현이 필요하다.

첫째로 == 연산자의 오버로딩, 두번째로 해시함수객체의 제공이다.  unordered_set의 2번째 파라메터인 Hash를 내가 사용하기 원하는 타잎을 Hash 할 수 있도록 제공 해 주는것이 필수적이다.

#include <iostream>
#include <string>
#include <unordered_set>

using namespace std;
using namespace std::tr1;

struct TTest
{
    int i;
    double d;

    bool operator == (const TTest &T) const
    {
      return ((i == T.i) && (d == T.d));
    }


};

struct TTestHash
{
    size_t operator () (const TTest &T) const
    {
        return T.i;  //그냥 간단하게 i값을 해시값 취급 해버렷다
    }
};

int main()
{
    TTest test[2];


    unordered_set<TTest, TTestHash> UnOrderSet;

    test[0].i = 5;
    test[0].d = 3.14;

    test[1].i = 9;
    test[1].d = 180.36;

    UnOrderSet.insert(test[0]);
    UnOrderSet.insert(test[1]);

    TTest FindValue;
    FindValue.i = 5;
    FindValue.d = 3.15;

    if(UnOrderSet.find(FindValue) != UnOrderSet.end())
    {
        cout << "찾는 객체가 있습니다" << endl;
    }
    else
    {
        cout << "찾는 객체가 없습니다" << endl;
    }
}

위처럼 사용자 정의타잎 TTest 를 정의하고, 그에대한 해시함수객체 TTestHash 를 정의한 후, unordered_set 을 생성할 시에, Hash함수 객체 타잎을 제공하엿다.



결론을 내자면...

1. 기본타잎을 쓰더라도 어느정도 데이터의 양을 예측 해야 만족스러운 성능이 나온다.
2. 사용자 정의타잎을 쓰고 싶으면 Hash 를 재정의 해야 하기때문에 얼마나 Hash 를 잘 시키느냐에 따라 성능이 크게 달라진다.
3. 위의 조건을 다 만족시킨다면 상황에따라 다르겠지만 대충 set 의 2배정도의 성능을 보여주는 것 같다(속도측면, 메모리는 아무래도 소비가 크다)
4. C++ Collection 너무 많다 =_=;;; 상황에 따라 최적의 Collection 을 찾는 것 만도 일이다.
5. STL 의 Collection 들은 별 존재가치가 없어졋단 생각도 든다... 메모리 아껴야되는 상황이 아니라면(오해의 소지 매우 많음!)

Ps. C++ 에서는 보통 Containers 라 하는 것 같은데... 익숙하지 않아 그냥 일반적인 Collection 이란 용어를 사용했다.
?

2008.10.05 23:38

[TR1 살펴보기] 2. Array

Lyn
조회 수 37340 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
예제코드

#include <iostream>
#include <array>

using namespace std;
using namespace std::tr1;

void main()
{
    array<int, 100> intarr;

    //초기화
    intarr.assign(0);  //모든 요소를 0으로 초기화한다
    for (int i = 0; i < 100; ++i)
    {
        cout << intarr[i] << " ";
    }
    //값을 대입해본다
    for (int i = 0; i < 100; ++i)
    {
        intarr[i] = i;
    }

    cout << endl << "Size : " << intarr.size() << endl;

    cout << "이터레이터를 사용한 루프" << endl;
    array<int, 100>::iterator ia;
    for (ia = intarr.begin() ; ia != intarr.end(); ++ia)
    {
        //이터레이터를 사용한 루프
        cout << *ia << " ";
    }
    cout << endl << "일반 배열처럼 접근하는 루프" << endl;
    for (int i = 0; i < 100; ++i)
    {
        cout << intarr[i] << " ";
    }

    //만약 범위를 벗어난다면 std::range_error 예외를 생성한다
//    intarr[100] = 1;
    system("pause");
}

TR1에서 추가된 array는 크기가 고정된 배열입니다.
즉 위에서의 array<int, 100> intarr 은 int intarr[100] 과 본질적으론 차이가 없습니다.

단지 관리를 편리하게 하기 위해 객체로 제공된다는것(C#, Java 와 같다고 보심 편합니다) 그리고 범위를 넘어설 시 예외를 발생한다는점이 특징입니다. (C의 배열은 범위를 넘어서도 치명적인 부분에 접근하기전까지는 오류발생을 모르는 경우도 있고.. 이경우 오류의 추적이 매우 어렵습니다)

C++ 표준 라이브러리의 일부가 될 TR1이므로 STL에서 사용하는 이터레이터 문법을 그대로 사용 할 수 있으며,
일반 배열과 본질적으로 같으므로 [] 연산자로 값을 읽고 쓸 수도 있습니다.

또한 swap, assign, size 등의 멤버함수를 제공하여, 초기화, 교체 등의 작업을 쉽게 할 수 있으며, 배열의 크기를 얻어 올 수도 있습니다.

배열에 비해 사용시의 오버헤드가 좀 있긴 하지만... 안정적인 프로그램의 메모리 관리를 위해서는 사용 해 볼만 합니다.
?

2008.10.05 23:37

[TR1 살펴보기] 1. Random

Lyn
조회 수 38093 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
참고사이트
http://www.boost.org/doc/libs/1_36_0/libs/random/index.html

예제소스
#include <iostream>
#include <random>
#include <windows.h>

using namespace std;
using namespace std::tr1;

void main()
{
    mt19937 Generator; //난수엔진
    uniform_int<> dst(100, 500); //범위지정자
    Generator.seed(GetTickCount());  //seed 초기화
    variate_generator<mt19937, uniform_int<> > rand(Generator, dst); //난수생성기

    for( int i = 0;i < 1000; ++i )
    {
       cout << rand() << endl;   //난수생성기는 () 연산자를 난수생성 연산자로 오버로딩 해 놓았습니다.
    }
}

TR1의 난수생성기는 3개의 요소로 이루어집니다.
1. 난수엔진
2. 범위지정자
3. 난수생성기

난수 엔진은 여러가지가 있으며,  대충 아래와같습니다.

정수난수엔진

minstd_rand
rand48
lrand48 (C 기본 라이브러리와 같음)
ecuyer1988
kreutzer1986
hellekalek1995
mt11213b
mt19937(C++0X 기본  난수엔진)

실수난수엔진 (전부 lagged_fibonacci 시리즈군요)
lagged_fibonacci607
lagged_fibonacci1279
lagged_fibonacci2281
lagged_fibonacci3217
lagged_fibonacci4423
lagged_fibonacci9689
lagged_fibonacci19937
lagged_fibonacci23209
lagged_fibonacci44497

아래로 갈 수록 랜덤의 성능이 좋아지지만, 메모리소모가 커지고 속도가 느려집니다.

만약 _HAS_CPP0X_ 매크로가 정의되어있다면,
mt19937엔진은 default_random_engine 라는 이름으로 typedef 됩니다.

Ps1. C++0X 표준에서는 variate_generator<mt19937, uniform_int<>> 처럼 템플릿의 >>를 붙여쓰는것을 허용합니다.
하지만 C++0X이전의 컴파일러에서는 >>를 시프트 연산자로 인식하여 오류를 내니 주의.
VS2008 Sp1은 >>를 정상적으로 템플릿으로 인식하며 CB2009는 오류를 냅니다.

Ps2. 위의 코드는 C++Builder 2009에서 제대로 실행되지 않습니다.
코드엔 이상이 없어 보이는데... 이상하게 Devide by Zero 익셉션을 뱉네요 ㅡ.ㅡ; 구현상의 버그인듯

Ps3. 위의 코드는 VS2008 SP1에서는 치명적인 오류를 가집니다. mt19937 엔진이 범위 밖의 숫자를 뱉어냅니다. 고쳐지기전까지 쓰지마세요(보이드소프트의 김호광님 감사합니다)
?

Board Pagination Prev 1 ... 5 6 7 8 9 10 11 12 13 14 Next
/ 14