연재 완료/자료구조 이론

9. 큐 활용 -a. 대기 손님 시뮬레이션

라이피 (Lypi) 2018. 11. 7. 22:42
반응형

대기 손님 시뮬레이션

  # 설명 생략(..)







큐 (대기자 목록 때문에 조금 수정)

 #pragma once

template <typename T>
struct node {
	T data;
	node<T>* next;
};

template <typename T>
class QueueList
{
	node<T>* pFront;
	node<T>* pRear;
	node<T>* pCursor;

	int iCount;

public:
	int Add(T data);
	int Remove();
	T  Peek();
	int Count();

	//대기 목록 보여주기용
	void ResetCursor();
	node<T>* Next(); 

public:
	QueueList();
	virtual ~QueueList();
};

template <typename T>
QueueList<T>::QueueList()
{
	pFront = nullptr;
	pRear = nullptr;
	iCount = 0;
}

template <typename T>
int QueueList<T>::Add(T data)
{
	node<T>* newnode = new node<T>;
	newnode->data = data;
	newnode->next = nullptr;

	if (pRear != nullptr) {
		pRear->next = newnode;
		if (pFront == nullptr) {
			pFront = pRear;
		}
	}
	else {
		pFront = newnode;
	}

	pRear = newnode;

	return ++iCount;
}

template <typename T>
int QueueList<T>::Remove()
{
	node<T>* pDel = pFront;
	pFront = pFront->next;
	if (--iCount == 0) {
		pRear = nullptr;
	}
	delete pDel;

	return 	iCount;
}

template <typename T>
T QueueList<T>::Peek()
{
	return pFront->data;
}

template <typename T>
int QueueList<T>::Count()
{
	return iCount;
}

//리스트 순회용 (대기자 리스트 보여주기 용)
template <typename T>
void QueueList<T>::ResetCursor()
{
	pCursor = pFront;
}

template <typename T>
node<T>* QueueList<T>::Next()
{
	node<T>* ret = pCursor;

	if (pCursor != nullptr && pCursor->next != nullptr) {
		pCursor = pCursor->next;
	}

	return ret;
}

template <typename T>
QueueList<T>::~QueueList()
{

}

시뮬레이터

#pragma once
#include "QueueList.h"

#include <iostream>

struct customer
{
	int iNumid;

	int iArrivalTurn;
	int iNeedTurn;
	int iStartTurn;

	int iEndTurn;
};

class simulator
{
private:
	bool customerEmpty;
	
	int customerId;
	QueueList<customer*> customerQueue;

	int iCurrentTurn;
	customer* CurCustomer;
	
private:
	void CustomerChange();
	bool ComeCustomer(int nt);

public:
	void Display();
	void Work(int n);

public:
	simulator();
	~simulator();
};

//---------------->

simulator::simulator()
{
	iCurrentTurn = 0;
	customerId = 1;
	customerEmpty = true;
	CurCustomer = nullptr;
}

void simulator::Display()
{
	system("cls");

	printf("손님이 왔다면 0이 아닌 수를 입력하세요. \n0은 손님이 오지 않은 것으로 처리됩니다. \n종료하고 싶으시면 999를 입력하세요\n");

	printf("현재 %d 턴 \n", iCurrentTurn);
	
	if (CurCustomer == nullptr) {
		printf("창구 : 손님이 없습니다.\n");
	}
	else {
		int remainTurn = CurCustomer->iNeedTurn - (iCurrentTurn - CurCustomer->iStartTurn);
		printf("창구 : %d번 손님 처리중 [남은 턴 : %d] \n", CurCustomer->iNumid, remainTurn);
	}

	customerQueue.ResetCursor();
	node<customer*>* wait = nullptr;
	do {
		wait = customerQueue.Next();
		if (wait == nullptr) {
			printf("대기 : 손님이 없습니다.\n");
			return;
		}
		else {
			printf("대기 : 대기자 목록 : %d번 [%d턴] \n", wait->data->iNumid, wait->data->iNeedTurn);
		}
	} while (wait->next != nullptr);
}

bool simulator::ComeCustomer(int nt)
{
	if (nt <= 0) {
		return false;
	}

	customer* nCustomer = new customer;
	nCustomer->iNumid = customerId++;
	nCustomer->iArrivalTurn = iCurrentTurn;
	nCustomer->iNeedTurn = nt;
	nCustomer->iStartTurn = 0;
	nCustomer->iEndTurn = 0;

	customerQueue.Add(nCustomer);

	return true;
}

void simulator::CustomerChange()
{
	if (customerQueue.Count() != 0) {
		CurCustomer = customerQueue.Peek();
		customerQueue.Remove();
		CurCustomer->iStartTurn = iCurrentTurn;
		CurCustomer->iEndTurn = iCurrentTurn + CurCustomer->iNeedTurn;
		customerEmpty = false;
	}
	else {
		CurCustomer = nullptr;
	}
}

void simulator::Work(int n)
{
	iCurrentTurn++;

	ComeCustomer(n);

	if (customerEmpty) {
		CustomerChange();
	}
	else {
		if (iCurrentTurn == CurCustomer->iEndTurn) {
			if (customerQueue.Count() != 0) {
				CustomerChange();
			}
			else {
				customerEmpty = true;
			}
		}
	}
}


simulator::~simulator()
{
	customerQueue.~QueueList();
}

메인

#include "header.h"

int main()
{
	simulator queueing;

	int enter;

	do {
		queueing.Display();
		std::cin >> enter;
		queueing.Work(enter);
	} while (enter < 999);
}


반응형