Enumを使って処理を分ける(c.f.第3回オフラインリアルタイムどう書くの参考問題)
第9回のどう書くの問題のおかげで気づきましたが、EnumのstaticメソッドのvalueOfはベンリですね!
文字を与えてEnumの値を取ってくるだけの基本的なメソッドです。なにをいまさらという感じですが……。
このメソッドを使えば、入力文字(char)による処理の振り分けがカンタンに書けます。
enum Foo { A { @Override void print() { System.out.println("Aです"); } }, B { @Override void print() { System.out.println("Bです"); } }, C { @Override void print() { System.out.println("Cです"); } }; abstract void print(); } public class Main { public static void main(String[] args) { Foo.valueOf("A").print(); } }
Aです
こんな感じに。
なので、たとえば、第3回の参考問題なども楽勝になります。
野球のボールカウント・アウトカウントの遷移を計算する。(得点・ランナー・イニング の計算は不要)
ただし、ストライク・ボール・ファウル・ヒット・ピッチャーフライしかない。
細かいルールは下記の通り:
- ストライクが3つになったらアウトが増え、ストライクとボールがゼロになる。
- ボールが4つになったらフォアボールになり、ストライクとボールがゼロになる。アウトは増えない。
- ヒットを打ったらストライクとボールがゼロになる。アウトは増えない。
- ピッチャーフライを打ったらストライクとボールがゼロになり、アウトが増える。
- アウトが3つになったら、アウト・ストライク・ボール全てゼロになる。
- ファウルの場合、もともとストライクが1以下の場合はストライクが増え、ストライクが2の場合には変化なし。
- 入力は "sbsfbhsshssbbffbbssbs" のように、ひとつながりの文字列として与えられる。
- s, b, f, h, p がそれぞれ ストライク、ボール、ファウル、ヒット、ピッチャーフライ を意味する。
(後略)
オフラインリアルタイムどう書く第三回の参考問題
sbfhpの各文字に対応するメソッドを定義して直接呼び出したいなーと悩んでいましたが、この程度ならEnumでできるわけです。
- 最初に書いた解答 http://d.hatena.ne.jp/torazuka/20120818/yhpg
- リフレクション編 http://d.hatena.ne.jp/torazuka/20120818/reflection
上記のようなことをする必要はありませんでした……。
書き直したら、結構短くなりました。
enum Rule { s { @Override int[] play(int[] count) { count[1] += 1; if (count[1] == 3) { count[0] += 1; count[1] = 0; } return count; } }, b { @Override int[] play(int[] count) { if ((count[2] += 1) == 4) { count[1] = 0; count[2] = 0; } return count; } }, f { @Override int[] play(int[] count) { if (count[1] < 2) { count[1] += 1; } return count; } }, h { @Override int[] play(int[] count) { count[1] = 0; count[2] = 0; return count; } }, p { @Override int[] play(int[] count) { count[0] += 1; count[1] = 0; count[2] = 0; return count; } }; abstract int[] play(int[] count); } /** * 問題: http://qiita.com/items/ebd8a56b41711ba459f9 */ public class BallCountEx { public String solve(String input) { int[] count = new int[3]; // out, strike, ball char[] charArray = input.toCharArray(); String result = ""; for (char each : charArray) { Rule rule = Rule.valueOf(String.valueOf(each)); count = rule.play(count); count = outCheck(count); for (int i : count) { result += i; } result += ","; } return result.substring(0, result.length() - 1); } private int[] outCheck(int[] count) { if (count[0] == 3) { count[0] = 0; count[1] = 0; count[2] = 0; } return count; } }
- 上のコードと、テストコード https://gist.github.com/torazuka/5329238
めでたし、めでたし。