問題
observer パターンでは、オブジェクトがサブジェクトを購読し、何かが起きるたびに通知を受け取ります。ここでは人がトピックを購読し、発行されたイベントはそのトピックの購読者全員に届きます。
各購読は <person> <topic> の形です。同じ購読を繰り返しても効果は増えません。次に events の各イベントはトピック名で、そのトピックの購読者はそれぞれ 1 件の通知を受け取ります。誰も購読していないトピックのイベントは捨てられます。
event_subscribers(subscriptions, events) を実装してください。
入力
subscriptions: "<person> <topic>" 形式の文字列(名前に空白は含まれません)。
events: 発行順のトピック名。
出力
購読が 1 件以上ある人ごとに "<person>:<count>" を、名前の順(文字コード順)に並べて返します。
制約
1 ≤ 購読の数 ≤ 10,000
0 ≤ イベントの数 ≤ 100,000
例
入力:
events = ["news", "sports", "weather"]
subscriptions = ["bob sports", "alice news", "alice sports"]
期待される出力:
expected = ["alice:2", "bob:1"]
入力:
std::vector<std::string> events = {"news", "sports", "weather"};
std::vector<std::string> subscriptions = {"bob sports", "alice news", "alice sports"};
期待される出力:
std::vector<std::string> expected = {"alice:2", "bob:1"};
入力:
string[] events = new string[] {"news", "sports", "weather"};
string[] subscriptions = new string[] {"bob sports", "alice news", "alice sports"};
期待される出力:
string[] expected = new string[] {"alice:2", "bob:1"};
解説
alice は news と sports を購読しているので両方を受け取ります。bob は sports だけ、weather は誰も購読していません: ["alice:2", "bob:1"]。
入力:
events = []
subscriptions = ["zoe tech", "zoe tech"]
期待される出力:
expected = ["zoe:0"]
入力:
std::vector<std::string> events = {};
std::vector<std::string> subscriptions = {"zoe tech", "zoe tech"};
期待される出力:
std::vector<std::string> expected = {"zoe:0"};
入力:
string[] events = new string[] {};
string[] subscriptions = new string[] {"zoe tech", "zoe tech"};
期待される出力:
string[] expected = new string[] {"zoe:0"};
解説
重複した購読は 1 回と数え、イベントは発行されていません: ["zoe:0"]。
解き方のヒント
まずは自分で考えてから、ヒントを 1 つずつ開いてみましょう。
ヒント 1
購読者をトピックごとにまとめると、各イベントの届け先がすぐ分かります。
ヒント 2
トピックごとに set を使えば、重複した購読は 1 回と数えられます。
ヒント 3
購読した人は通知が 0 件でも結果に含めます。
目安の計算量
時間 O(購読数 + イベント数 × トピックあたりの購読者数)、追加メモリ O(購読数)
参考資料
この課題はCodeUtility用に調整されています。上記の説明と制約に従ってください。