C++/summary

집합클래스 - 배열, 리스트 , 맵

gandus 2010. 11. 24. 11:11

 
nMFC 배열 클래스의 특징
—배열 인덱스를 잘못 참조하는 경우 오류를 발생시킨다.
—배열 크기가 가변적이다.


이것은 템플릿 클래스이다.



CPoint 는 좌표이도, String이나 포인트 등




 
n비 템플릿 클래스
—afxcoll.h 헤더 파일  가 포함되어야 한다.

정수나 문자열 같은거는 미리 만들어진것을 사용하는게 좋다

하지만 내가 만든 포인트같은것은 위에 처럼  템플릿을 사용하는게 좋다.






CStringArray array;

array.SetSize(5);

for(int i=0; i<5; i++){

    CString string;

    string.Format("%d년이 지났습니다.", i*10);

    array[i] = string;

}


for(i=0; i<5; i++)

            // 출력하려면 기본형으로 타입캐스팅 해야한다.
   
cout << (LPCTSTR)array[i] << endl;





CUIntArray array;

array.SetSize(5);

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

    array[i] = i;

// 배열 원소 삽입
//  3에 77을 넣고, 기존 3은 우측으로 밀어낸다.

array.InsertAt(3, 77);

for(i=0; i<array.GetSize(); i++)

    cout << array[i] << endl;

cout << endl;

// 배열 원소 삭제

array.RemoveAt(3);

for(i=0; i<array.GetSize(); i++)

    cout << array[i] << endl;

 

 





 

nMFC 리스트 클래스
 
n템플릿 클래스
—afxtempl.h 헤더 파일



 

 


n비 템플릿 클래스
—afxcoll.h 헤더 파일







/****   리스트를이용한예제이다.   ***/

 

 

 

/****  비 템플릿을 이용   ***/



              
//
포인터배열이다.

               char *szFruits[ ] = {

                       "사과",

                       "딸기",

                       "포도",

                       "오렌지",

                       "자두"

               };

 

               CStringList list;

 

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

                       list.AddTail(szFruits[i]); // 마지막에붙인다.

 

               // 리스트제일앞에서출발하여순환한다.

               POSITION pos = list.GetHeadPosition();

               // 시작위치를가리킨다.

              

               while(pos != NULL){

                       CString string = list.GetNext(pos);  // 반환값이문자열-실값이넘어온다.

                       // GetNext(pos)  - 전달은pos(위치를넘겨)

                       // pos 값이바뀌는것은pass by reference

                       cout << (LPCTSTR)string << endl;

               }

               cout << endl;

               // 리스트제일뒤에서출발하여순환한다.

               pos = list.GetTailPosition();

               while(pos != NULL){

                       CString string = list.GetPrev(pos);

                       cout << (LPCTSTR)string << endl;

               }

               // POSITION 타입의변수pos는이전의예제에서선언한것이다.

               pos = list.Find("포도");

               list.InsertBefore(pos, "살구");

               list.InsertAfter(pos, "바나나");

               list.RemoveAt (pos);

 

 

               // 항목삽입과삭제후결과를확인한다.

               pos = list.GetHeadPosition();

               while(pos != NULL){

                       CString string = list.GetNext(pos);

                       cout << (LPCTSTR)string << endl;

               }

 

               // POSITION 타입의변수pos는이전의예제에서선언한것이다.

               pos = list.Find("포도");

               list.InsertBefore(pos, "살구");

               list.InsertAfter(pos, "바나나");

               list.RemoveAt (pos);

 

               // 항목삽입과삭제후결과를확인한다.

               pos = list.GetHeadPosition();

               while(pos != NULL){

                       CString string = list.GetNext(pos);

                       cout << (LPCTSTR)string << endl;

               }





/****   템플릿을이용한예제  ***/


               // Point3D 객체를 저장할 수 있는 리스트 객체를 생성한다. 
                CList<Point3D, Point3D&> list;

 

 

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

                       list.AddTail(Point3D(i, i*10, i*100));

 

               POSITION pos = list.GetHeadPosition();

 

               while(pos != NULL){

                       Point3D pt = list.GetNext(pos);

                       cout<< pt.x << ", " << pt.y  <<", " << pt.z <<endl;

               }




실습문제 )  리스트 1~10 사이의 임의의수 100개를 저장하고
사용자로부터 정수를 입력받아 삭제 후 출력

- 중복된 정수는 없을때 까지 삭제한다.



/*

               실습문제)  리스트1~10 사이의임의의수100개를저장하고

               사용자로부터정수를입력받아삭제후출력

 

               - 중복된정수는없을때까지삭제한다.

               */

 

 

               srand((unsigned)time(NULL)); // 현시각을기준으로난수생성           

               int r , a, input;

 

               // 정수형리스트를작성한다.

               CList<int, int&> list;

       

               POSITION pos;

 

 

               for(int i=0; i< 100; i++){

 

                       // 1~ 100 정수선언

                       r = rand() %10 + 1;

 

                       list.AddTail(r);

               }

 

 

               pos = list.GetHeadPosition();

 

 

               while(pos != NULL){

                       a = list.GetNext(pos);

                       cout <<  a <<" ";

               }

 

              

               cout<<endl<< "지우실값을입력하시오. : ";

               cin>> input; cout<<endl;     

 

 

 

               // 위치를받는다.

                pos = list.Find(input);

 

               while(pos != NULL){

 

                       list.RemoveAt(pos);                  

                       pos = list.Find(input);

               }

 

               pos = list.GetHeadPosition();

 

               while(pos != NULL){

                       a = list.GetNext(pos);

                       cout <<  a <<" ";

               }





 




 

n 동작 원리

- 언제 사용하는게 좋은가?? 
사전같이 검색을 빠르게 하도록 - 키값이 존재한다.


키가 다르더라도 값이 같을수 있기 때문에 키 값이 존재한다.

해쉬함수로 검색후 그리고 순차접근을 한다.
 
 
n템플릿 클래스
—afxtempl.h 헤더 파일







 키,  키, 데이터,  데이터 4개를 넘겨준다.





n비 템플릿 클래스
—afxcoll.h 헤더 파일






키는 정수 아니면 문자열

키에 대해서 해쉬 함수로 주소값을 얻어내야한다.

정수 문자열 외는 만들어서 사용해야한다.




UINT AFXAPI HashKey(CString& str)

{

    LPCTSTR key = (LPCTSTR) str;

    UINT nHash = 0;

    while(*key)

        nHash = (nHash<<5) + nHash + *key++;

    return nHash;

}

 

CMap<CString, CString&, UINT, UINT&> map;

        map[CString ("사과")] = 10;



map["사과 "]     < ------->    map[CString ("사과")] = 10;


차이점은???

map[사과] 는

문자열이지만, 타입은 char *    =  (LPCSTR) 과 같이 기본형인데.



UINT AFXAPI HashKey(CString& str)
함수에서는 객체를 원하기 때문에


map[CString ("사과")]  -   CString s= CString ("사과")

이것과 같으므로

타입은 CString 객체이다.

이 객체를 넘기는 것이다.