Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++로 전화번호부 시스템 설계하기

이번 글에서는 다음과 같은 연산을 지원하는 전화번호부(Phone Directory)를 C++로 설계하는 방법을 알아보겠습니다.

  • get – 아직 아무에게도 할당되지 않은 번호를 하나 반환합니다.
  • check – 특정 번호가 현재 사용 가능한지 여부를 확인합니다.
  • release – 사용 중이던 번호를 회수하여 다시 사용할 수 있도록 반환합니다.

생성자(initializer)를 통해 처음에 총 n개의 번호를 초기화할 수 있습니다.

해결 접근 방법

이 문제는 집합(set)큐(queue) 두 가지 자료구조를 활용하면 효율적으로 해결할 수 있습니다. 단계별로 살펴보겠습니다.

  1. 사용 중인 번호를 관리할 집합 s를 정의합니다.
  2. 아직 배정 가능한 번호를 보관할 큐 available을 정의합니다.
  3. 생성자는 maxNumbers를 매개변수로 받습니다.
  4. N := maxNumbers로 설정합니다.
  5. i := 0부터 i < N까지 반복하면서 각 번호 i를 available 큐에 삽입합니다.

get() 함수

  1. available의 크기가 0이면 -1을 반환합니다.
  2. x := available의 첫 번째 원소를 가져옵니다.
  3. x를 집합 s에 삽입합니다.
  4. available에서 해당 원소를 제거합니다.
  5. x를 반환합니다.

check() 함수

  1. number가 N 이상이거나 0 미만이면 false를 반환합니다.
  2. 그렇지 않으면 number가 집합 s에 없는 경우 true를 반환합니다(사용 가능 상태).

release() 함수

  1. check(number)가 true라면 이미 사용 가능한 번호이므로 그대로 종료합니다.
  2. x := number로 설정합니다.
  3. s에서 x를 삭제합니다.
  4. x를 available 큐에 삽입하여 재사용 대기열에 넣습니다.

예제 코드

아래 구현 예제를 통해 더 잘 이해해 보겠습니다.

#include <bits/stdc++.h>
using namespace std;
class PhoneDirectory {
public:
    set<int> s;
    queue<int> available;
    int N;
    PhoneDirectory(int maxNumbers){
        N = maxNumbers;
        for (int i = 0; i < N; i++) {
            available.push(i);
        }
    }
    int get(){
        if (available.size() == 0)
            return -1;
        int x = available.front();
        s.insert(x);
        available.pop();
        return x;
    }
    bool check(int number){
        if (number >= N || number < 0)
            return false;
        return s.find(number) == s.end();
    }
    void release(int number){
        if (check(number))
            return;
        int x = number;
        s.erase(x);
        available.push(x);
    }
};
main(){
    PhoneDirectory ob(3);
    cout << (ob.get()) << endl;
    cout << (ob.get()) << endl;
    cout << (ob.check(2)) << endl;
    cout << (ob.get()) << endl;
    cout << (ob.check(2)) << endl;
    ob.release(2);
    cout << (ob.check(2)) << endl;
}

입력

ob.get();
ob.get();
ob.check(2);
ob.get();
ob.check(2);
ob.release(2);
ob.check(2);

출력

0
1
1
2
0
1

동작 과정 설명

최대 3개의 번호(0, 1, 2)로 초기화된 상황을 가정해 보겠습니다.

  • 첫 번째 get() 호출 → 번호 0이 배정되고, 결과는 0입니다.
  • 두 번째 get() 호출 → 번호 1이 배정되고, 결과는 1입니다.
  • check(2) 호출 → 번호 2는 아직 배정되지 않았으므로 true(1)입니다.
  • 세 번째 get() 호출 → 번호 2가 배정되고, 결과는 2입니다.
  • check(2) 호출 → 번호 2는 이제 사용 중이므로 false(0)입니다.
  • release(2) 호출 후 check(2) 호출 → 번호 2가 회수되어 다시 사용 가능하므로 true(1)입니다.

이처럼 set과 queue를 조합하면 get, check, release 세 연산 모두 효율적으로 처리할 수 있는 전화번호부를 구현할 수 있습니다.