天下一プログラマーコンテスト
以下の文字列はUTF-8を文字エンコーディング形式とする16進数のバイト列である。
http://www.klab.jp/tenka1programer/bosyu.html
UTF-8でエンコーディングされた文字列として解析した場合、この文字列の【文字数】を答えなさい。
この問題を、sed、tr、wcでやってみる。
$ sed 's/\(.\)./\1/g' <<EOT | tr -d '89ab\n' | wc -c > e4bba5e4b88be381aee69687e5ad97e58897e381af5554462d38e38292e69687e5ad97 > e382a8e383b3e382b3e383bce38387e382a3e383b3e382b0e5bda2e5bc8fe381a8e381 > 99e3828b3136e980b2e695b0e381aee38390e382a4e38388e58897e381a7e38182e3828be38082 > EOT 41
よって、答えは41。
念のため、何が書いてあったのかRuby(1.9)で確認。
p [<<EOT.delete("\n")].pack('H*').force_encoding('UTF-8') e4bba5e4b88be381aee69687e5ad97e58897e381af5554462d38e38292e69687e5ad97 e382a8e383b3e382b3e383bce38387e382a3e383b3e382b0e5bda2e5bc8fe381a8e381 99e3828b3136e980b2e695b0e381aee38390e382a4e38388e58897e381a7e38182e3828be38082 EOT
中身は、"以下の文字列はUTF-8を文字エンコーディング形式とする16進数のバイト列である。" だった。
おぼえがき
2進数 | 16進数 | UTF-8での意味 |
---|---|---|
0bbb | 0〜7 | 1バイト文字 |
10bb | 8〜b | 2〜6バイト文字非先頭 |
110b | c,d | 2バイト文字先頭 |
1110 | e | 3バイト文字先頭 |
1111 | f | 4〜6バイト文字先頭 |
上位4ビットしか見てないので5〜6バイト文字が使われていた場合は正しく処理できないことになるが、以下によると問題なさそう。
UTF-8 - Wikipedia
http://ja.wikipedia.org/wiki/UTF-8
5〜6バイト
* Unicodeの範囲外(どんな文字が登録されるかという計画も無い)
追記
perl で最短っぽい書き方をすると、こんな?
perl -pe"$_=s/..([8-b].)*//g"http://d.hatena.ne.jp/miau/20090618/1245353984
これはうまい。
perlのsコマンドは置換後文字列じゃなくて置換数を返すので、今回のお題にはうってつけだ。