山傘のプログラミング勉強日記

プログラミングに関する日記とどうでもよい雑記からなるブログです。

[AtCoder] ABC049C - 白昼夢 / Daydream

文字列に関する問題

AtCoder Beginners Selectionを進めていいるんですが、解答に詰まった問題があったので、記事にしたいと思います。 AtCoder Beginners Selection - AtCoder

問題はCランクの問題で、問題文は下になります。 ABC049C - 白昼夢 / Daydream

最初に考えたコード

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        scanner.close();
 
 
        String s1 = s.replace("dreamer", "");
        String s2 = s1.replace("dream", "");
        String s3 = s2.replace("eraser", "");
        String s4 = s3.replace("erase", "");
 
        String t1 = s.replace("dream", "");
        String t2 = t1.replace("dreamer", "");
        String t3 = t2.replace("eraser", "");
        String t4 = t3.replace("erase", "");
 
        String u1 = s.replace("dreamer", "");
        String u2 = u1.replace("dream", "");
        String u3 = u2.replace("erase", "");
        String u4 = u3.replace("eraser", "");
 
        String o1 = s.replace("dream", "");
        String o2 = o1.replace("dreamer", "");
        String o3 = o2.replace("erase", "");
        String o4 = o3.replace("eraser", "");
 
        boolean flag1 = s4.length() == 0;
        boolean flag2 = t4.length() == 0;
        boolean flag3 = u4.length() == 0;
        boolean flag4 = u4.length() == 0;
 
        if(flag1 || flag2 || flag3 || flag4) {
            System.out.println("YES");
        }else {
            System.out.println("NO");
        }
    }
}

このコードはいくつかのテストデータをクリアできますが、不正解となるテストデータもあります。 このコードは特定の文字列を空白に置き換えることを、その文字列の選ぶ順番によって置き換え後の文字列のサイズが0かどうかを調べています。 この方法では、例えば、"e + dream + r + dream + a + erase + s + dream + e + eraser" のような文字列も置き換えによってサイズが0となっていまします。

正解となったコード

import java.util.Scanner;
 
public class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        scanner.close();
 
        int sLen = s.length();
        boolean flag = true;
        String []w = {"dreameraser", "dreamerase", "dreamer", "eraser",
                "dream", "erase"};
        int begin = 0;
        int end = 0;
        while(flag) {
            if(begin == sLen) {
                if(sLen == 0) {
                    System.out.println("NO");
                    break;
                }else {
                    System.out.println("YES");
                    flag = false;
                    break;
                }
            }else {
                for(int i = 0; i < 7; i++) {
                    if(i == 6) {
                        System.out.println("NO");
                        System.exit(0);
                    }
                    end = begin + w[i].length();
                    //System.out.println("end " + end);
                    if(end <= sLen) {
                        String sub = s.substring(begin, end);
                        //System.out.println(sub);
                        if(sub.equals(w[i])) {
                            begin = end;
                            //System.out.println(i + " " + begin);
                            break;
                        }
                    }
                }
            }
 
        }
 
    }
}

このコードは入力された文字列の一部ととあらかじめ用意した部分文字列の配列wと一致するものを探しだすことで、検査を行っています。

感想

AtCoderではテストデータを見ることができない?ので、何が原因で間違ったどうかを調べる術がありません。 与えられたサンプルデータをパスしたとしても、その他のデータで不正解となることがあるので、注意が必要です。