ログの レベルと 単語の集計
- 文字列の処理
- 問題 05
- やさしい
- 目安 11 分
サーバーの
本番の
入力は
問題
ある
- 時刻は
09:05:30のように、時、 分、 秒を 2 桁ずつ 並べた 8 文字です - レベルは
ERROR、WARN、INFO、DEBUGのどれかです - メッセージは、
英小文字だけの 単語が 1 個以上、 空白 1 つで 区切られて 並んだものです
ログの
- レベルごとの
行の 数。 ERROR、WARN、INFO、DEBUGの順に、 1 行に 1 つずつ、 レベルの 名前と 行の 数を 空白 1 つで 区切って 書きます。 1 行も 無い レベルも 0 と書きます - 調べたい
単語の それぞれに ついて、 その 単語を メッセージの 単語として 含む行の 数。 与えられた 順に 1 行ずつ書きます
単語をlogin は relogin のrelogin というlogin を
入力の形式
N
時刻 レベル 単語 単語 ...
...
Q
w_1
w_2
...
w_Q1 行目に
出力の形式
4 + Q 行を
制約
- N と Q は、
どちらも 1 以上 100000 以下の整数です - 1 行の
メッセージの 単語は 1 個以上 5 個以下です - メッセージの
単語と 調べたい 単語は、 どれも 英小文字 1 文字以上 10 文字以下です - 時刻は 00 時 00 分 00 秒から 23 時 59 分 59 秒までで、
行は 時刻の 順に 並んでいます
入力と出力の例
例 1
`ERROR` が
入力
5 09:00:01 INFO user login ok 09:00:05 ERROR db timeout 09:01:10 INFO user login ok 09:02:00 WARN slow db query 09:03:30 ERROR relogin failed 4 login db timeout cache
出力
ERROR 2 WARN 1 INFO 2 DEBUG 0 2 2 1 0
例 2
1 行に
入力
2 23:59:58 DEBUG retry retry retry 23:59:59 DEBUG done 2 retry done
出力
ERROR 0 WARN 0 INFO 0 DEBUG 2 1 1
ヒント
まだ開いていません
付箋は 3 枚。下の段ほど答えに近づきます
ヒント 2
ヒント 3答えに近い
全部の
先に
解答
ログを 1
Python
Python
import sys
lines = sys.stdin.read().split("\n")
n = int(lines[0])
levels = {"ERROR": 0, "WARN": 0, "INFO": 0, "DEBUG": 0}
lines_with = {}
for i in range(n):
parts = lines[1 + i].split()
levels[parts[1]] += 1
for word in set(parts[2:]):
lines_with[word] = lines_with.get(word, 0) + 1
q = int(lines[1 + n])
out = [f"{name} {count}" for name, count in levels.items()]
for i in range(q):
word = lines[2 + n + i].strip()
out.append(str(lines_with.get(word, 0)))
print("\n".join(out))JavaScript
JavaScript
const lines = require("fs").readFileSync(0, "utf8").split("\n");
const n = Number(lines[0]);
const levels = new Map([["ERROR", 0], ["WARN", 0], ["INFO", 0], ["DEBUG", 0]]);
const linesWith = new Map();
for (let i = 0; i < n; i++) {
const parts = lines[1 + i].trim().split(" ");
levels.set(parts[1], levels.get(parts[1]) + 1);
for (const word of new Set(parts.slice(2))) {
linesWith.set(word, (linesWith.get(word) ?? 0) + 1);
}
}
const q = Number(lines[1 + n]);
const out = [];
for (const [name, count] of levels) out.push(`${name} ${count}`);
for (let i = 0; i < q; i++) {
const word = lines[2 + n + i].trim();
out.push(linesWith.get(word) ?? 0);
}
console.log(out.join("\n"));計算量
ログを 1 回読んで
遅い
よく ある間違い
- 行の
中に 単語が 含まれるかを、 行の 文字列の 部分 一致 (Python の in、JavaScript の includes) で調べ、 reloginの行を loginとして数えてしまう。 単語に 分けてから比べます - 時刻や
レベルまで 単語として 数え、 ERRORという単語を 調べた ときに 行の 数が 出てしまう。 メッセージは 3 つ目の 欄からです - 1 行に
同じ 単語が 何度も 出てくる 行を、 出てきた 回数だけ 数えてしまう - 0 行の
レベルを 出力しない、 または レベルを 辞書に 入れた 順ではなく 名前の 順に 並べてしまう。 決まった 順の 4 行を、 いつも 全部書きます
解答を動かした版 Python 3.12.14Node.js 22.23.4確認日 2026/10/31