プログラミングを上達させたい

情報学専攻の大学院→放送局でCMの営業など@大阪→舞台俳優&IT営業@東京

CodinGameで解けなかった問題(Javaでの文字列処理)

引き続き、CodinGameのClash of Codeをやっています。楽しい・・!
ただ、小さい問題の早解きコンテストでありながら、解けないorかなり手こずるような問題もあります。
だいたいは文字列絡みでつまずきます。
自分用のメモも兼ねて、解けなかった問題を解き直したものを書きます。

文字列に"何種類の文字が使われているか"を計算する問題

たしか、文字列(アルファベットのみ)に9種類以上のアルファベットが使われているか調べなさい、みたいな問題でした。
問題を見て、「よく分からないけど正規表現で書けるのでは?」みたいに思って調べたのですが見つからず・・・
結局時間切れで終わってしまいました。

とりあえず汚くてもよいから解こう!ということで、つらつらコードを書いてみました。
方針としては(入力文字列を"abcba"として)、

①文字列を分割した、1文字ずつの配列に直す
"abcde" ⇒ ["a", "b", "c", "b", "a"]

②配列を集合に直す(これによって重複がなくなる)
["a", "b", "c", "b", "a"] ⇒ {"a", "b", "c"}

③この集合のサイズを出力
{"a", "b", "c"} ⇒ 3

という感じです。

書いてみてはエラーや変な動作と戦って(AtCoderのコードテストを使って動作確認しました、便利ですね)、
それで完成コードがこちらです。

import java.util.*;
import java.io.*;
import java.math.*;

class Main {

    public static void main(String args[]) {
        Scanner in = new Scanner(System.in);
        String S = in.nextLine();

        String[] strs = S.split("");   //文字列を分割するのはこう書くんですって
        List<String> lst = Arrays.asList(strs);    //集合に直すために、まずはリストに
	Set<String> st = new HashSet<String>(lst);    //集合に直す

        System.out.println(st.size() - 1);    //『- 1』の理由は後で説明します
    }
}

最後にサイズから『- 1』をしている理由ですが、上記のコードで『st』はどうなっているかというと

[, b, c, a]

となっていて、サイズは何故か『4』となってしまいます。おそらく「空文字列」が入っちゃうんですね。
めんどうなんで、「1引く」で解決することにしました。


という話でした。
Javaの文字列処理について、色々調べ周りながら戦っています。
また、ちょいちょいコードゴルフ的な問題も出てきてます。その辺はめちゃくちゃ弱いですね・・・Javaというのもあるんですが。コードゴルフ用の言語を1つ習得したいところ。

以上です、引き続き頑張るぞ!


追記(この記事を書いてから1ヶ月半後、7/22)

Clash of Codeで似たような問題がShortest mode(=コードゴルフ)で出ました。
問題は「入力される文字列に何種類のアルファベットが使われているか、大文字と小文字の差は無視して答えよ」です。
最近使っているJavaScriptで書いてみたら、思いの外きれいにシンプルにできたので、ここに書きます。

print(new Set(readline().toLowerCase().split('')).size)

我ながらきれいー!
ヒュー!


しかし!!!1位ではありませんでした。
1位のhard-codedさんの書いたコード(Ruby)はコチラ

p gets.upcase.chars.uniq.size

"uniq"って便利ね!!!!
追記終わり。