Python
 Computer >> コンピューター >  >> プログラミング >> Python

Pythonで座席予約マネージャーを実装する方法|SeatReserveManagerクラスの作り方を解説

本記事では、n個の座席の予約状態を管理するシステムをPythonで設計・実装する方法を解説します。座席には1からnまでの番号が振られており、これらを効率的に管理する「SeatReserveManager」クラスを作成していきます。

実装すべき機能の概要

SeatReserveManagerクラスには、以下の3つの機能を実装します。

  • コンストラクタ(__init__):引数としてnを受け取り、1からnまでの番号が付いたn個の座席を管理するオブジェクトを初期化します。初期状態では、すべての座席が予約可能です。
  • reserve():現時点で予約されていない座席の中から最も番号の小さい座席を取得し、その座席を予約した上で、座席番号を返します。
  • unreserve(seatNumber):指定されたseatNumberに該当する予約済みの座席を1つ解放し、再び予約可能な状態にします。

動作例

例えば、以下のような一連の操作を行った場合を考えてみましょう。

  • obj = SeatReserveManager(7)
  • obj.reserve()
  • obj.reserve()
  • obj.reserve()
  • obj.unreserve(2)
  • obj.unreserve(5)
  • obj.reserve()
  • obj.reserve()

この場合の出力は 1, 2, 3, 2, 5 となります。処理の流れを追うと、まず座席1・2・3を順に予約し、その後座席2と5を解放しようとしています。ただし、この時点では座席5はまだ予約されていないため、実際に解放されるのは座席2のみです。その後のreserve()呼び出しでは、空いた座席2が最優先で割り当てられ、次に新たな座席4ではなく空き状況に応じた座席5が返される、という挙動になります。

アルゴリズムの考え方

この問題は、以下の手順で解決できます。

  • コンストラクタでnを受け取り、内部状態を初期化します。
  • current_seat := 0 — 最後に予約された座席番号を記録する変数です。
  • empty_seats := 空のリスト — 解放された(再度予約可能になった)座席番号を格納するリストです。
  • reserve()関数を定義します。
    • empty_seatsの長さが0より大きい場合:
    • s := empty_seats内の最小値
    • empty_seatsからsを削除
    • sを返す
  • empty_seatsが空の場合は、current_seatを1増やして返します。
  • unreserve()関数を定義します。引数としてseatNumberを受け取ります。
  • seatNumberをempty_seatsの末尾に追加します。

Pythonでの実装コード

それでは、上記のアルゴリズムを実際のPythonコードで確認してみましょう。

class SeatReserveManager:
   def __init__(self, n):
      self.current_seat = 0
      self.empty_seats = []

   def reserve(self):
      if len(self.empty_seats) > 0:
         s = min(self.empty_seats)
         self.empty_seats.remove(s)
         return s
      self.current_seat += 1

      return self.current_seat

   def unreserve(self, seatNumber):
      self.empty_seats.append(seatNumber)

obj = SeatReserveManager(7)
print(obj.reserve())
print(obj.reserve())
print(obj.reserve())
obj.unreserve(2)
obj.unreserve(5)
print(obj.reserve())
print(obj.reserve())

入力

obj = SeatReserveManager(7)
print(obj.reserve())
print(obj.reserve())
print(obj.reserve())
obj.unreserve(2)
obj.unreserve(5)
print(obj.reserve())
print(obj.reserve())

出力

1 2 3 2 5

計算量について

この実装では、reserve()メソッド内でmin()とremove()を使用しているため、最悪の場合O(k)の計算時間がかかります(kは解放済み座席リストのサイズ)。より大規模なシステムでは、ヒープ(heapqモジュール)を使って最小値の取得をO(log k)に高速化したり、ソート済みコンテナを活用することでパフォーマンスを改善できます。座席数が多い実運用のシステムでは、こうしたデータ構造の選択が重要になります。

まとめ

今回は、Pythonで座席の予約状態を管理するSeatReserveManagerクラスを実装しました。ポイントは以下の通りです。

  • 新規予約には連番で次の座席を割り当てる
  • 解放された座席はリストで管理し、次回の予約時に最小番号を優先的に再利用する
  • シンプルなリスト実装でも動作するが、ヒープを使うと効率が向上する

このような座席管理のロジックは、映画館やイベント会場の予約システムなど、実際のアプリケーションでも応用できる基本的かつ重要なパターンです。ぜひ自身のコードにも取り入れてみてください。

  1. Pythonプログラムの実行方法まとめ!IDLE・コマンドライン・PyCharmなど5つの方法を解説

    コードを書いたら、次はそれを実行して出力結果を確認する必要があります。プログラムを実行することで、書いたコードが正しく動作し、期待通りの結果が得られるかどうかをチェックできます。幸いなことに、Pythonプログラムの実行はとても簡単です。この記事では、代表的な5つの実行方法をわかりやすく解説します。IDLEで実行するPythonに標準で付属しているIDLEを使ってプログラムを実行するには、以下の手順に従います。Pythonのコードを書いて保存します。メニューから「Run > Run Module」を選択するか、キーボードのF5キーを押すだけで実行できます。IDLEは初心者にとって扱いやす

  2. 【Python入門】randint()関数でじゃんけんゲームを実装する方法

    Pythonを使えば、手軽に面白いミニゲームを開発できます。その代表例のひとつが「じゃんけんゲーム」です。本記事では、標準ライブラリのrandomモジュールが提供するrandint()関数を使って、コンピュータと対戦できるじゃんけんゲームを実装する方法を解説します。 実際のじゃんけんでは、プレイヤーは掛け声に合わせて拳(グー)を振り下ろしながら、グー・チョキ・パーのいずれかの手を出します。このプログラムではその流れを再現し、ユーザーの入力とコンピュータのランダムな選択を比較して勝敗を判定します。 じゃんけんゲームの基本ルール まず、じゃんけんの勝敗ルールをおさらいしておきましょう。 グー v