언어 자료구조 알고리즘/Escort 자료구조와 STL

[자료구조와 STL] 9.vector를 이용하여 특정 키 순으로 보관하기 예제 코드

언제나휴일 2016. 4. 18. 10:21
반응형

  vector를 이용하여 특정 키 순으로 보관하기 예제 코드

 

//EHGlobal.h

#pragma once

#pragma warning(disable:4996)

#include <string>

using std::string;

#include <iostream>

using std::cout;

using std::cin;

using std::ostream;

using std::endl;

#include <conio.h>

#include <windows.h>

enum keydata

{

    NO_DEFINED,F1,F2,F3,F4,F5,F6,F7,ESC

};

 

//공통적으로 사용할 정적 메서드를 캡슐화한 클래스

class ehglobal

{

public:

    static void clrscr();//화면을 지우는 메서드

    static void timeflow(int millisecond); //원하는 시간동안 지연시키는 메서드

    static int getnum();//수를 입력받는 메서드

    static string getstr();//문자열을 입력받는 메서드

    static keydata getkey();//기능 키를 입력받는 메서드

private:

    ehglobal(void){ }//개체를 생성하지 못하게 하기 위해 private으로 접근 지정

    ~ehglobal(void){}

};

  

//EHGlobal.cpp

#include "ehglobal.h"

 

void ehglobal::clrscr()//화면을 지우는 메서드

{

    system("cls");

}

 

void ehglobal::timeflow(int millisecond) //원하는 시간동안 지연시키는 메서드

{

    Sleep(millisecond);

}

 

int ehglobal::getnum()//정수를 입력받는 메서드

{

    int num;

    char buf[255+1];

    cin.getline(buf,255); //버퍼에 입력받음

    cin.clear();//cin 내부 버퍼를 지움

    sscanf(buf,"%d",&num); //포맷에 맞게 버퍼에 내용을 정수로 변환

    return num;

}

 

string ehglobal::getstr()//문자열을 입력받는 메서드

{

    char buf[255+1];

    cin.getline(buf,255);

    cin.clear();

    return buf;

}

 

keydata ehglobal::getkey()//기능 키를 입력받는 메서드

{

    int key = getch();

 

    if(key == 27) //ESC를 누를 때의 key 값이 27

    {

        return ESC;

    }

    if(key == 0) //기능 키를 눌렀을 때는 getch의 반환값이 0

    {

        //어떤 기능 키를 눌렀는지 확인하려면 getch를 다시 호출해야 함

        //사용자에게 다시 키를 입력받는 것은 아님

        key = getch();

        switch(key) //입력한 키에 따라 약속된 값 반환

        {

        case 59: return F1;    case 60: return F2;

        case 61: return F3;    case 62: return F4;

        case 63: return F5;    case 64: return F6;

        case 65: return F7;

        }

    }

    return NO_DEFINED; //열거되지 않은 키를 눌렀을 때

}

 

//Stu.h

#pragma once

#include "EhGlobal.h"

class Stu

{

    const int num; //상수 멤버 변수

    string name;

public:

    Stu(int num,string name): num(num),name(name) //멤버 초기화 구문

    {

    }

    int GetNum()const{    return num;    }

    string GetName()const{   return name;    }

    friend ostream &operator<<(ostream &os,Stu *stu)

    {

        os<<"번호:"<<stu->num<<"이름"<<stu->name<<endl;

        return os;

    }

};

 

//StuManager.h

#pragma once

#include "Stu.h"

typedef vector<Stu *> StuCollection;

typedef vector<Stu *>::iterator StuIter;

 

class StuManager

{

    StuCollection base; //학생을 보관하는 컬렉션(vector)

public:

    ~StuManager(void);

    void Run();

private:

    keydata SelectMenu();

    void AddStu();

    void RemoveStu();

    void SearchStuByNum();

    void SearchStuByName();

    void ListAll();

};

 

//학생 번호와 멤버 변수 num이 같으면 참을 반환하는 함수 개체 클래스

class CompareByNum

{

    int num;

public:

    CompareByNum(int num)

    {

        this->num = num;

    }

    //함수 호출 연산자 중복 정의 메서드

    bool operator()(Stu *stu)

    {

        return (stu && stu->GetNum() == num);

    }

};

 

//학생 이름와 멤버 변수 name이 같으면 참을 반환하는 함수 개체 클래스

class CompareByName

{

    string name;

public:

    CompareByName(string name)

    {

        this->name = name;

    }

    bool operator()(Stu *stu) //함수 호출 연산자 중복 정의

    {

        return (stu && stu->GetName() == name);

    }

};

 

//StuManager.cpp

#include "StuManager.h"

StuManager::~StuManager(void) //반복자를 통해 보관된 모든 학생 요소 소멸

{

    StuIter seek = base.begin();

    StuIter end = base.end();

    Stu *stu = 0;

    for ( ;seek != end; ++seek)

    {

        stu = *seek; //반복자의 간접 연산의 결과는 보관한 요소(학생 위치 정보)

        delete stu;

    }

}

void StuManager::Run()

{

    keydata key=0;

    while((key = SelectMenu())!=ESC)

    {

        switch(key)

        {

        case F1: AddStu(); break;

        case F2: RemoveStu(); break;

        case F3: SearchStuByNum(); break;

        case F4: SearchStuByName(); break;

        case F5: ListAll(); break;

        default: cout<<"잘못된 메뉴를 선택하였습니다."<<endl;

        }

        cout<<"아무키나 누르세요"<<endl;

        ehglobal::getkey();

    }

}

keydata StuManager::SelectMenu()

{

    ehglobal::clrscr();

    cout<<"메뉴 [ESC]:종료"<<endl;

    cout<<"[F1]:학생 추가 [F2]:학생 삭제 [F3]:번호로 검색";

    cout<<" [F4]:이름으로 검색 [F5]:전체 보기"<<endl;

    cout<<"메뉴를 선택하세요"<<endl;

    return ehglobal::getkey();

}

//학생의 번호가 멤버 변수 num보다 크거나 같으면 참을 반환하는 함수 개체 클래스

class MoreEqualByNum

{

    int num;

public:

    MoreEqualByNum(int num)

    {

        this->num = num;

    }

    bool operator()(Stu *stu)

    {

        return (stu && stu->GetNum() >= num);

    }

};

 

void StuManager::AddStu()

{

    int num = 0;

    cout<<"추가할 학생 번호를 입력하세요."<<endl;

    num = ehglobal::getnum();

    MoreEqualByNum sbn(num);

    StuIter seek = find_if(base.begin(),base.end(),sbn); //보관할 위치 찾기

    if((seek== base.end())||((*seek)->GetNum() != num)) //없다면

    {

        string name = "";

        cout<<"이름을 입력하세요"<<endl;

        name = ehglobal::getstr();       

        base.insert(seek,new Stu(num,name)); //seek 앞에 보관

    }

    else

    {

        cout<<"이미 존재하는 학생입니다."<<endl;

    }

}

 

bool StuManager::Exist(int num)

{

    StuIter seek = base.begin();

    StuIter end = base.end();

    Stu *stu=0;

    for( ; seek != end; ++seek)

    {

        stu = *seek; //반복자의 간접 연산의 결과는 보관된 요소(학생 위치 정보)

        if( stu->GetNum() == num)

        {

            return true;

        }

    }

    return false;

}

void StuManager::RemoveStu()

{

    int num = 0;

    cout<<"삭제할 학생 번호를 입력하세요."<<endl;

    num = ehglobal::getnum();

    CompareByNum sbn(num); //학생 번화가 num과 같으면 참 반환

    StuIter seek = find_if(base.begin(),base.end(),sbn);

    if(seek== base.end())//참인 곳이 없음

    {

        cout<<num<<"번 학생 자료는 보관되지 않았습니다."<<endl;

        return;

    }

    Stu *stu = *seek;

    delete stu;

    base.erase(seek); //특정 위치에 보관된 요소를 지우는 메서드

}

void StuManager::SearchStuByNum()

{

    int num = 0;

    cout<<"검색할 학생 번호를 입력하세요."<<endl;

    num = ehglobal::getnum();

    CompareByNum sbn(num); //함수 개체 선언

    StuIter seek = find_if(base.begin(),base.end(),sbn);

    if(seek== base.end())//참인 곳이 없음

    {

        cout<<num<<"번 학생 자료는 보관되지 않았습니다."<<endl;

        return;

    }   

    Stu *stu = *seek; //간접 연산의 결과는 보관된 요소(학생 위치 정보)

    cout<<stu<<endl;

}

void StuManager::SearchStuByName()

{

    string name="";

    cout<<"검색할 학생 이름을 입력하세요."<<endl;

    name = ehglobal::getstr();

    CompareByName sbn(name); //함수 개체 선언

    //구간 내에 요소들을 함수 개체를 적용했을 때 처음 참인 위치 찾음

    StuIter seek = find_if(base.begin(),base.end(),sbn);

    if(seek== base.end())//참인 곳이 없음

    {

        cout<<name<<"번 학생 자료는 보관되지 않았습니다."<<endl;

        return;

    }

    Stu *stu = *seek;

    cout<<stu<<endl;

}

void StuManager::ListAll()

{

    //차례대로 보여주기 위해 전체 구간의 반복자를 얻어옮

    StuIter seek = base.begin();

    StuIter end = base.end();

 

    Stu *stu = 0;

    for ( ;seek != end; ++seek)

    {

        stu = *seek;

        cout<<stu<<endl;

    }

}

 

//Demo.cpp

#include "StuManager.h"

void main()

{

    StuManager *sm = new StuManager();

    sm->Run();

    delete sm;

}

 

반응형