【AIZU ONLINE JUGDE】「錬金マスター/Wrought Gold Master」を学習する

Javaについて、基礎中の基礎は終わったような感じがしてきた。

しかし、まだ自信というほどのものはない。それは主に、「知ってる技が少ない=メソッドやクラスに関する知識が足りない」ことと「アルゴリズムのパターンを知らない」ことが原因かと思っている。

そう悩んでいたところ、AIZU ONLINE JUGDEというサイトに当たった。このサイトでは、いろんな言語に関する練習問題を多く載せてくれている。

難度は「”Hello World”を出力しなさい」という簡単な問題から、よく練られたアルゴリズムが要求されるような問題まで、いろんなレベルの問題が揃い、独学の身にとっては嬉しい。
さらに、このサイトは他の人の書いた(正解の)コードも公開されているため、これが非常に勉強になる。

というわけで、諸先輩方のコードを拝見させてもらいながら勉強してみようと思う。今回の問題は「錬金マスター/Wrought Gold Master」というもの。

模範解答

以下、sawfishさんのコードより。コメントアウトは、コボリが勝手に付け足しています。

学習

おおまかな流れ

  1. アイテムのインスタンスを作り、そのインスタンスの中にレシピリストを作り、必要なアイテム(インスタンス)を登録する。
  2. 指定されたアイテムについて、「レシピが存在しなければ、購入金額が最低費用」、「存在するなら、素材ごとの最小費用の合計を最小値」とする

非常にシンプルな処理。自分だったらItemクラスとRecipeクラスを作ってしまいそうだ。たしかに、必要な素材はアイテムの情報として登録すべきだろう。

インスタンスの作成方法

まず気になったのが、下の箇所。

Item item = getItemInstance(br.readLine());
itemTable.put(item.name, item);

自分がインスタンスを作るときは、たいてい配列でインスタンスを作っていたのだが(item[0]みたいな)、模範解答では、

「itemインスタンスを生成する」→「マップにアイテムの名前とインスタンスを登録する」→「itemインスタンスを生成する」→「マップに登録」

の繰り返しでインスタンスを生成し、コントロールできるようにしている。これをすることで、(例えば今回のように)名前からあるインスタンスを持ってくることができるようになる。すごい。

また、2回目にitemインスタンスを生成するとき、1回目に生成したitemインスタンスを上書きするものだと思っていたが、どうやらそういう訳でもないらしい。
「new Item」とコードを書くぐらいだから、きっと新規作成なのだろう。

三項条件演算子

if文の省略について、そろそろ勉強してもよいだろう。単純な処理はこういった1行で済むコードで済ませておきたいところ。

条件式 ? 式1 : 式2

「式1」は、条件がtrue出会った場合。「式2」はfalseの場合。

StringTokenizerクラスについて

レシピをつくるときに、StringTokenizerクラスを使っているのも勉強になった。これは入力された文章を半角スペースごとに区切ってくれるクラスメソッド(?)だ。これまで、標準入力を読み取って、その文字列をsplitメソッドで分けて処理していたが、このような方法もある。
ちなみに、nextToken()で次の文字列(トークン)を取得し、countToken()で残りの文字列の数を取得できるよう。