Pythonで複数のメールボックスから重要なメールをラウンドロビン順に抽出するプログラム
本記事では、複数のメールボックスからジャンクメールを除外し、重要なメールだけを1つのリストにまとめるPythonプログラムを紹介します。
問題の概要
複数のメールボックス(リスト)が与えられます。各メールボックスには文字列のリストが格納されており、それぞれの文字列は次のいずれかを表します。
- 「J」: ジャンクメール(Junk)
- 「P」: 個人メール(Personal)
- 「W」: 仕事メール(Work)
最初のメールボックスから順にラウンドロビン方式(各メールボックスを1通ずつ順番に巡回する方式)でメールを取り出し、「J」を除外した結果を1つのリストとして返すのが目的です。
入力例と出力例
たとえば、入力が以下の場合を考えてみましょう。
mailboxes = [["W", "P"], ["J", "P", "J"], ["W"]]
フィルタリング前の取得順序は W → J → W → P → P → J となります。ここからジャンクメール「J」を除外すると、最終的な出力は次のようになります。
["W", "W", "P", "P"]
解法のアプローチ
この問題は、以下の手順で解くことができます。
- メールボックスの総数を
n_mailboxesとして取得します。 - 結果を格納するための空リスト
resultを用意します。 - 各メールボックスの読み込み位置を記録する
countsリストを、要素数n_mailboxes・すべて0で初期化して作成します。 - ループ継続フラグ
moreをTrueに設定します。 moreが真である限り、以下を繰り返します。moreをFalseにリセットします。- i を 0 から
n_mailboxes - 1まで順に処理します。indexにcounts[i]を、mailboxにmailboxes[i]を代入します。indexがそのメールボックスのサイズ未満であれば:moreをTrueにします(まだ未処理のメールが残っているため)。counts[i]を1増やします。mailにmailbox[index]を代入します。mailが「J」でなければ、resultの末尾に追加します。
- すべての処理が完了したら
resultを返します。
Pythonでの実装例
それでは、実際のコードを見てみましょう。
class Solution:
def solve(self, mailboxes):
n_mailboxes = len(mailboxes)
result = []
counts = [0] * n_mailboxes
more = True
while more:
more = False
for i in range(n_mailboxes):
index, mailbox = counts[i], mailboxes[i]
if index < len(mailbox):
more = True
counts[i] += 1
mail = mailbox[index]
if mail != "J":
result.append(mail)
return result
ob = Solution()
mailboxes = [["W", "P"], ["J", "P", "J"], ["W"]]
print(ob.solve(mailboxes))入力
[["W", "P"], ["J", "P", "J"], ["W"]]
出力
['W', 'W', 'P', 'P']
コードのポイント
このアルゴリズムのポイントは、counts リストによって各メールボックスのどこまで読み込んだかを管理している点です。これにより、メールボックスごとの長さが異なっていても、正しくラウンドロビン形式で巡回できます。また、more フラグは「まだ処理していないメールが1つでも残っているかどうか」を判定する役割を担っており、全メールボックスの末尾に到達した時点でループが終了します。
計算量は、メールの総数をN、メールボックスの数をMとすると O(N × M) となります。各パスで全メールボックスをチェックする必要があるためです。ただし、実用上は十分高速に動作します。
-
Pythonで文字列からn番目の文字を削除する方法
この記事では、「文字列から指定したインデックス(i番目)の文字を削除して表示する」という問題の解き方を解説します。 問題の概要 与えられた文字列から、指定されたインデックス位置にある1文字を取り除き、その結果を出力します。 Pythonでは文字列のインデックスは必ず0から始まる点に注意してください。たとえば「tutorialspoint」という文字列の場合、各文字とインデックスの対応は以下のようになります。 T u t o r i a l s p o i n t 0 1 2 3 4 5 6 7 8 9 10 11 12 13 それでは、この問題を解くためのPythonスクリプトを見ていきましょ
-
PythonでIPアドレスから先行ゼロ(先頭の0)を削除する方法
IPアドレスには、オクテットごとに余分な先行ゼロ(先頭の「0」)が含まれていることがあります。例えば「200.040.009.400」のような表記は、正規の形式では「200.40.9.400」と表されます。この問題を解決する基本的な考え方はシンプルです。まずIPアドレスの文字列を「.」(ドット)で分割し、各部分を整数型(int)に変換します。整数への変換時点で先頭のゼロは自動的に取り除かれるため、その後、再び文字列に戻して「.」で連結すれば、整形済みのIPアドレスが完成します。実行例入力 : 200.040.009.400 出力 : 200.40.9.400アルゴリズムStep 1: IPアド