2011年12月16日金曜日

TopCoder SRM281 Div2 250Pts

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

ランレングス符号化とは同じ文字が連続して続く文字列を文字の発生回数とその文字によって圧縮するという手法である。例えば"AAAABBBCDDE"を圧縮すると"4A3BC2DE"である。1はこの例のように省略されることもあるし、そうでないこともある。前に正の整数がオプションとしてつけられたアルファベットの大文字からなる任意の文字列は適切にエンコードされた文字列と呼ばれる。適切にエンコードされたtextという文字列が与えられたときに、デコードされた文字列を返せ。もし、デコードされた文字列の長さが50文字を超えるようであれば、"TOO LONG"という文字列を返せ(ダブルクォートは不要)。

私の解答はこちら。

public class RunLengthEncoding {

 public String decode(String text) {
  StringBuffer sb = new StringBuffer();
  int n = 1;
  boolean isPrevNum = false; // 直前の文字は数字だったか
  for( int i=0 ; i<text.length() ; i++ ){
   if( Character.isDigit(text.charAt(i)) ){
    if( isPrevNum == true){
     n = n*10+Integer.parseInt(text.substring(i, i+1)); // 数値の更新
     if( n>50 ) return "TOO LONG"; // 途中で50を超えたら終了
    }else{
     // 直前がアルファベットだったら注目する文字を数値化
     n = Integer.parseInt(text.substring(i, i+1));
     isPrevNum = true;
    }
   }else{ // 数字とその文字からデコードを行う
    StringBuffer tmp = new StringBuffer();
    for( int j=0 ; j<n ; j++ ) tmp.append(text.charAt(i));
    sb.append(tmp);
    n = 1;
    isPrevNum = false;
   }
  }
  String ret = sb.toString();
  // デコードした結果、長すぎと分かった場合
  if( ret.length() > 50 ) return "TOO LONG";
  return ret;
 }

}

得点は199.34/250、中央値は約121点。提出者の正解率は約52%とやや低め。最初のコンパイルでコンパイルエラーがでたのは、途中で50を超えたら終了するというロジックがなかった点である。このロジックを入れないと、10000000000000000000Aのような符号化された文字が現れたときに、整数型で扱える範囲を超えておかしくなってしまうというのが原因だった。

0 件のコメント:

コメントを投稿

フォロワー

ブログ アーカイブ

ページビューの合計