しろあんのさかな

ふーちゃのエンジニアブログ

ABC049C - 白昼夢 / DaydreamをJavaでといてみる

AtCoder Beginners Selectionという練習問題で気づいためも。最善のコードではなくて、失敗談的なところも書いてるので、コピペして参考にするには雑かも。(理由は文章で)
こんなコードもあるのかなと参考にはなるかもしれません。
問題はこちら ABC049C - 白昼夢 / Daydream

解法1:オフセットを考慮した解法

やっかいなのは、"er"が、dreamerのものなのか、eraserまたはeraseのものなのかを考えること。(以降、"er"割り当て問題とします。)そこで、dreamerase, dreameraserをつくり、dreameraser, dreamerase, dreamer, dream, eraser, eraseの順番で処理すればいいかなという戦略でした。

もう少し説明

dream/eraserなのかdream/eraseなのかをdreamerを判定する前に判定することで"er"割り当て問題を解決できます。辞書を増やすという形で解決する方法です。

改善できるところ

これでも動きますが、offsetというか、for文のインデックス処理が間違いやすいので、もう少しシンプルに解ける方法を探しました。(解法2)

コード

import java.util.*;
public class Main{
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    String S = sc.next();
    if(S.charAt(0) != 'd' && S.charAt(0) != 'e') {
        System.out.println("NO");
        return;
    }

    for(int i = 0; i <= S.length() ; i++) {
        int leftLen = S.length() - i;
        if(leftLen == 0) {
        System.out.println("YES");
        return;
        }
        if(leftLen >= 11 && S.substring(i,i+11).equals("dreameraser")){
        i = i+10;
        }else if(leftLen >= 10 && S.substring(i,i+10).equals("dreamerase")) {
        i = i+9;
        }else if(leftLen >= 7 && S.substring(i,i+7).equals("dreamer")) {
        i = i+6;
        }else if(leftLen >= 5 && S.substring(i,i+5).equals("dream")) {
        i = i+4;
        }else if(leftLen >= 6 && S.substring(i,i+6).equals("eraser")) {
        i = i+5;
        }else if(leftLen >= 5 && S.substring(i,i+5).equals("erase")) {
        i = i+4;
        }else{
        System.out.println("NO");
        return;
        }
    }
    System.out.println("NO");
    }
}

解法2:Stringクラスの置き換えメソッドを利用した解法

Stringクラスの置き換え関数(replace関数)を使う解法。ファイルの編集などで置換するとき、無意識に気にしている方法かもしれません。replaceする順番が鍵になります。"er"割り当て問題を意識すると、eraser, erase, dreamer, dreamの順番に入れ替えればいいことがわかります。

コード

import java.util.*;
public class Main{
    public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    String S = sc.next();
    S = S.replace("eraser", "").replace("erase", "").replace("dreamer", "").replace("dream", "");
    if(S.length() == 0) {
        System.out.println("YES");
    }else{
        System.out.println("NO");
    }
    }
}

まとめ

ABC049C - 白昼夢 / DaydreamをJavaでといた話。クラスの関数はもう少し引き出しとして知っておいた方が良さそうだと感じました。もう一つ正規表現のやり方を思いついたけれど正規表現で一発変換しようとしていろいろ試して挫折しました。(良い書き方があれば教えてください)