はじめに
paizaラーニングはプログラミング学習が出来るプラットフォームです。
問題はランク付けしてあり、ランクが上がると難易度がアップします。
paizaラーニングのレベルアップ問題はユーザー同士で解答を教え合ったり、コードを公開することが可能です。
自分が難しいと感じた問題のコードを解説することでスキルアップをする事が今回の目的でした。
誤りや改善点がありましたらご指摘頂けますと嬉しいです。
お題
お題のリンク
問題文
1行目に行数を表す整数 n、続く n 行の各行で「文字」と「整数」の組が空白区切りで入力されます。
n 個の組について、「文字」の値が同じ組同士の数値を足しあわせてまとめ、まとめた数値の降順で
文字とまとめた数値の組を出力してください。
この際、まとめた数値は重複しません。
入力される値
入力は以下のフォーマットで与えられます。
n
S_1 D_1
S_2 D_2
...
S_i D_i
...
S_n D_n
S_i は「文字」で、D_i は「整数」です。
入力値最終行の末尾に改行が1つ入ります。
文字列は標準入力から渡されます。
期待する出力
文字とまとめた数値の組を各行で出力してください。
文字と数値は半角スペースで区切ってください。
お手本コード
num = int(input())
inputs = {}
result = {}
for i in range(num):
tmp = input().split()
exist = False
for (key, value) in inputs.items():
if key == tmp[0]:
exist = True
if exist:
inputs[tmp[0]] = inputs[tmp[0]] + int(tmp[1])
else:
inputs[tmp[0]] = int(tmp[1])
# ソート用にkeyとvalueを反転させた辞書を作る
for (key, value) in inputs.items():
result[value] = key
result = sorted(result.items(), reverse=True)
for i in result:
print(i[1] + " " + str(i[0]))
解説
考え方
以下の考え方で実現します
- 標準入力が何回行われるかという値を取得してfor文の繰り返し回数に指定する。2~5を繰り返す
- 標準入力で受け取った値を辞書のキーとバリューとして使う値に分割する
- 2で取得したキーの値が既出かどうかを確認する
- 既出の場合は1で取得したバリューを辞書内の同キーのバリューに足算する
- 未出の場合は1で取得したキーとバリューを辞書に追加する
- 2~5で作成した辞書をソートするためにキーとバリューを反転した辞書を作成する
- 6で作成した辞書をsorted関数で降順にソートする。キーと値のタプルのリストになる
- 7で作成したリストからキー、バリューに使用していた値を繰り返して出力する
2~5のコードの詳細
初見で考え方は思い付いたのですが、お手本を見るまでは実現させるイメージがつきませんでした。
お手本コード内の以下の箇所にあたります。
for i in range(num):
tmp = input().split()
exist = False
for (key, value) in inputs.items():
if key == tmp[0]:
exist = True
if exist:
inputs[tmp[0]] = inputs[tmp[0]] + int(tmp[1])
else:
inputs[tmp[0]] = int(tmp[1])
取得したキーの値が既出かどうかを確認する の判断は
毎回、作成段階のリストからキーを一つずつ取り出して、今回のキーと同じであるか比較します。
初期値をFalseに設定しておき、同じであればTrueを返します。
Trueの場合は作成中辞書の今回のキーのバリューを今回のバリューと足算した値にします。
False、未出の場合は今回のキーとバリューを辞書に追加します。
コードの改善箇所
@shiracamus さんに改善点をご教示頂いたのでシェアしたいと思います。
ありがとうございます!
前述の2~5のコード箇所の簡略化
取得したキーの値が既出かどうかを確認する 箇所を
if tmp[0] in inputs: の一行で行うことが出来ます。
for i in range(num):
tmp = input().split()
if tmp[0] in inputs:
inputs[tmp[0]] = inputs[tmp[0]] + int(tmp[1])
else:
inputs[tmp[0]] = int(tmp[1])
前述の6~7のコード箇所の簡略化
反転した辞書は不要で、キーを対象としてソートを行うことが可能です。
以下一行で実現出来ます
result = sorted(inputs.items(), key=lambda x: x[1], reverse=True)
処理速度が向上したり、視認性が良くなるのでより良いコードを知れる事はすごく嬉しいです。
おわりに
競技プログラミングな問題は「考え方」と「実現方法」の理解が大切ですね。
今は問題を一つでも多くといて自分の中に吸収していきたいです。