0
0

モチベーション

ランキングづけのアルゴリズムの問題で少し悩んだので,少し考察してみました.
なお,単純化のため,個別のパターンの計算量最適化は考慮していません.
あくまで,ランキングづけ問題の複数のパターンを一般化して整理してみよう!というモチベーションです.

発想

すべての問題について,各参加者のエントリを定義することで,考えやすくなります.
エントリ内に必要な情報を,

  • 入力される情報
  • 参加者のランキング
  • 出力時に必要な情報

の3つに分けて考えると良いかなと思います.

問題例

以下の各パターンでは,参加者のテストの点数が与えられるので,それをランクづけした上で,所定の形式で出力することが求められます.

例1

入力:参加者の名前とスコアの組が,順番に与えられる
出力:参加者の名前とそのランキングを,入力の順に出力する

# 入力 
shinji 60
rei 100
asuka 95
mari 80

# 出力
shinji 4
rei 1
asuka 2
mari 3

例2

入力:参加者の名前とスコアの組が,順番に与えられる
出力:参加者の名前を,ランキング順に出力する

# 入力 
shinji 60
rei 100
asuka 95
mari 80

# 出力
rei
asuka
mari
shinji

例3

入力:参加者のスコアが順番に与えられる
出力:ランキングを,入力の順に出力する

# 入力
60
100
95
80

# 出力
4
1
2
3

解答例

例1

入力:参加者の名前とスコアの組が,順番に与えられる
出力:参加者の名前とそのランキングを,入力の順に出力する

従って,エントリ内に必要な情報は

  • 名前,テストの点数(=入力される情報)
  • 参加者のランキング
  • 入力時の順番(=出力時に必要な情報)

の3つです
したがって,各参加者のエントリは以下のように定義すると良いはずです.

# 入力直後
children=[
    {'name':'shinji','score':60,'rank':None,'id':0,},
    {'name':'rei','score':100,'rank':None,'id':1,}
    {'name':'asuka','score':95,'rank':None,'id':2,}
    {'name':'mari','score':80,'rank':None,'id':3,}
]

# ランクづけの処理を行う

# ランキングづけ後
children=[
    {'name':'shinji','score':60,'rank':4,'id':0,},
    {'name':'rei','score':100,'rank':1,'id':1,}
    {'name':'asuka','score':95,'rank':2,'id':2,}
    {'name':'mari','score':80,'rank':3,'id':3,}
]

入力が与えられた時点ではrankはNoneになっていますが,入力が全て与えられた後,各参加者のrankを計算する処理を実行すれば良いでしょう.
例1で重要なのは,出力時に,入力時の順番を覚えておく必要がある点です.
そのために,上記の配列childrenでは,各エントリに入力順(id)を定義しています

例2

入力:参加者の名前とスコアの組が,順番に与えられる
出力:参加者の名前を,ランキング順に出力する

従って,エントリ内に必要な情報は

  • 名前,テストの点数(=入力される情報)
  • 参加者のランキング

例1と基本的には同じですが,例2の場合は,出力時はランキング順に出力するので,入力時の順番は不要です.したがって,各参加者のエントリは以下のようになります.

# 入力直後
children=[
    {'name':'shinji','score':60,'rank':None},
    {'name':'rei','score':100,'rank':None}
    {'name':'asuka','score':95,'rank':None}
    {'name':'mari','score':80,'rank':None}
]

# ランクづけの処理を行う

# ランキングづけ後
children=[
    {'name':'shinji','score':60,'rank':4},
    {'name':'rei','score':100,'rank':1}
    {'name':'asuka','score':95,'rank':2}
    {'name':'mari','score':80,'rank':3}
]

例3

入力:参加者のスコアが順番に与えられる
出力:ランキングを,入力の順に出力する

従って,エントリ内に必要な情報は

  • テストの点数(=入力される情報)
  • 参加者のランキング
  • 入力時の順番(=出力時に必要な情報)

です.
例1,2と違うのは,参加者の名前が不要ということです,
(名前のような)参加者固有の情報が与えられないので,「点数に対してランクづけする」という風に解釈してしまうと,頭がこんがらがります.
ですから,入力時の順番を参加者固有のidとして各エントリ内に保持して,出力時はidでソートすれば良いでしょう.

# 入力直後
children=[
    {'score':60,'rank':None,'id':0,},
    {'score':100,'rank':None,'id':1,}
    {'score':95,'rank':None,'id':2,}
    {'score':80,'rank':None,'id':3,}
]

# ランクづけの処理を行う

# ランキングづけ後
children=[
    {'score':60,'rank':4,'id':0,},
    {'score':100,'rank':1,'id':1,}
    {'score':95,'rank':2,'id':2,}
    {'score':80,'rank':3,'id':3,}
]

まとめ

入出力時に必要な情報をまとめて,エントリとして定義する ことが重要.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0