このTopCoderの問題はこちらで見ることができる(要TopCoder登録 & 問題文は英語)。問題についておおまかに説明する。
あなたはギターを大量に所持しており、ギターはそれぞれ異なったシリアルナンバーを持っている。シリアルナンバーを高速に検索できるようにしたいので、ソートすることにした。各シリアルナンバーはA-Z、0-9の文字のみからなる。シリアルナンバーAがシリアルナンバーBより前にくるか確認するのは次のステップを踏む。
- AとBが違う長さであれば、短い方が先に来る。
- AとBの文字列の長さが同じになる場合、AとBに現れる数字の各桁の総和が小さい方が先に来る。A-Zの数字は0扱い。
- それでもAとBに違いがでない場合はアルファベット順になるようにする。
私の解答はこちら。
import java.util.Arrays;
public class SerialNumbers {
public String[] sortSerials(String[] serialNumbers) {
String[] ret = new String[serialNumbers.length];
sortBySerial[] obj = new sortBySerial[serialNumbers.length];
for( int i=0 ; ilt;obj.length ; i++ ){
obj[i] = new sortBySerial(serialNumbers[i]); // ソートのためのオブジェクトに値をセット
}
Arrays.sort(obj); // これでオブジェクトがソートされたので、
for( int i=0 ; ilt;ret.length ; i++ ){
ret[i] = obj[i].str; // sortBySerialオブジェクトからStringのみを取得して、
}
return ret; // ソートした結果を返却する
}
}
class sortBySerial implements Comparablelt;sortBySerialgt;{
String str; // 文字そのもの
int nStr; // 文字に現れる数字の合計
public sortBySerial(String s){ // ソートのためのオブジェクトのコンストラクタ
this.str = s;
int n = 0;
for( int i=0 ; ilt;s.length() ; i++ ){
if( s.charAt(i) gt;= '0' && s.charAt(i) lt;= '9') n += s.charAt(i)-'0';
}
this.nStr = n;
}
public int compareTo(sortBySerial obj){ // ソートのルールを実装
if( str.length() != obj.str.length() ){
return str.length() - obj.str.length();
}else if( nStr != obj.nStr ){
return nStr - obj.nStr;
}else{
return str.compareTo(obj.str);
}
}
}得点は204.29/250、1回のsubmitでシステムテストクリア。中央値は約97点と低め。ソートのルールが複雑なので、2重ループを1つのメソッドに書くより簡単だろうということで、Comparableを利用。過去に書いたComparableのコードを流用したので高速に解答できたはず。

0 件のコメント:
コメントを投稿