2011年12月20日火曜日

TopCoder SRM287 Div2 250Pts

このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題文について、おおまかに説明する。

文字列型のcustomerNames[]という、データベースから抽出された顧客のリストが与えられる。あなたのやることは1度よりも多くリストに現れた人と、その現れた回数を報告することである。レポートは文字列型の配列で返す。配列の各要素は"NAME OCCURS"という形式で返す。NAMEは顧客の名前で、OCCURSは顧客がリスト中に登場した回数である。出力は顧客の名前でアルファベット順にするようにせよ。なお、顧客名は常に大文字のみからなる。

私の解答はこちら。

import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;

public class CustomerStatistics {

 public String[] reportDuplicates(String[] customerNames) {
  // 顧客の名前でソートしたいのでHashMapを利用する
  TreeMap<String,Integer> tm = new TreeMap();
  for( int i=0 ; i<customerNames.length ; i++ ){
   if( tm.containsKey(customerNames[i]) == false ){ // 初登場の名前
    tm.put(customerNames[i], 1);
   }else{
    int n = tm.get(customerNames[i]); // 登場回数を記録し、
    tm.remove(customerNames[i]); // 情報を取り除き、
    tm.put(customerNames[i], n+1); // 1つ加えてハッシュに入れる
   }
  }
  // イテレータは順序があれば、その順序は保証することになっている
  // ただのMapなどでは順序が保証されない。
  Iterator<String> it = tm.keySet().iterator(); 
  ArrayList<String> aList = new ArrayList();
  while( it.hasNext() ){
   String s = it.next();
   int val = tm.get(s);
   if( val >= 2 ){
    aList.add(s + " " + val); // 条件に合うものだけ取り出しリストに入れる
   }
  }
  // リストを配列に変換する。引数のnew String[0]がポイント。
  String[] ret = (String[])aList.toArray(new String[0]);
  return ret;
 }

}

得点は169.21/250、中央値は約213点。Listを配列に変換する方法が分からなくて苦労していた。toArrayメソッドはしっていただが、new String[0]を引数に取らなかったために、ClassCastExceptionが発生して解くのに時間がかかってしまった。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計