Code Complete を読んでいて、テーブル駆動方式というものを知った.
条件分岐のロジックを配列やテーブルにデータをもたせ、そこからデータ取得することで処理を行う方式
入力されたキーで分岐して何か処理させたいとき、 普通はif文やswitch文を利用するのだけれども、 テーブル(配列)を利用すると、処理が短くかけるというテクニック.
- キーが数値のときは配列をつかう
- キーが文字のときは連想配列をつかう
テーブルには値を入れてもいいし、オブジェクトや無名関数をいれてもいい.
前回取り組んだ TopCoder SRM 675 Div2 Easy問題に適用してみた.
問題
異なる長さの単位の変換を考える.
- 1 ft = 12 in
- 1 yd = 3 ft
- 1 mi = 1760 yd
amount と fromUnit と toUnit が与えられるので、 toUnit の単位の amountを計算せよ!
普通の解き方
条件を全てif文で分岐して解く.
class LengthUnitCalculator:
def calc(self, amount, fromUnit, toUnit):
if fromUnit == toUnit:
return amount
if fromUnit == "in":
if toUnit == "ft":
return amount / 12
elif toUnit == "yd":
return amount / (12 * 3)
elif toUnit == "mi":
return amount / (12 * 3 * 1760)
if fromUnit == "ft":
if toUnit == "in":
return amount * 12
elif toUnit == "yd":
return amount / 3
elif toUnit == "mi":
return amount / (3 * 1760)
if fromUnit == "yd":
if toUnit == "in":
return amount * 3 * 12
elif toUnit == "ft":
return amount * 3
elif toUnit == "mi":
return amount / 1760
if fromUnit == "mi":
if toUnit == "in":
return amount * 12 * 3 * 1760
elif toUnit == "ft":
return amount * 3 * 1760
elif toUnit == "yd":
return amount * 1760
return 0.0
テーブル駆動方式
連想配列をつかって、キーと値を対応づける.
class LengthUnitCalculator:
def calc(self, amount, fromUnit, toUnit):
units = {
'in': 1,
'ft': 12,
'yd': 36,
'mi': 63360
}
return float(amount) * units[fromUnit] / units[toUnit]
うーん、鮮やか!!