@johtaniの日記 2nd

@johtani ‘s blog 2nd edition

第1章の03から04までやってみた(言語処理100本ノック)

Rustで言語処理100本ノックの続きで、03と04です。

03. 円周率

問題はこちら

入力文字列を.split_whitespace()で分割しておいて、単語ごとのベクタを作り出し、そこに対して文字を数えました。「アルファベットの」という注意書きがあるので”,“や”.“は含めずに数えるのかなということで、 charの.is_alphabetic()A-zまでの判定をしつつ、文字のベクタを作ってから、そのベクタの長さを詰め込むという感じでやりました。

これ、ひょっとして、collectでベクタにしなくても、i32とかの変数でカウントするとベクタ作らなくてもいいなじゃにか?というのに書きながら気づいた。。。 必要じゃないオブジェクトを作ってるよなぁ。

.filter().mapとかかな?この辺りの操作がイマイチ苦手。Javaでもまだ馴染めてないところなんだよなぁ。頭固すぎ。

04. 元素記号

問題はこちら

大作ですね。何だろう、大作。。。 最終的に連想配列(辞書型もしくはマップ型)」ということだったので、BTreeMapに詰め込んでます。 HashMapでもいいんですが、文字列で出力した時にキーが並んで見やすいからという理由で、BTreeMap使いました。それ以上の理由はないです。普通にやるなら、HashMapかな?

入力として、1文字だけの出力をする場所(インデックス番号)の配列を受け取ってます。1点だけ、チェックしていない、けど入力値の想定をしていて、idx_one_symbolsがソートされていて、小さいものから順番に出てくるものとしてます。関数作って、チェックすべきかな?

で、指定された場所の最後のものが入力文字列よりも大きいかどうかというチェックもしています。(あー、テストケース書いてないな)この辺りのせいでちょっと長めになってます。

単語の配列を作るのは03の時と同じやり方です。 回しかたがちょっと違って、.iter().enumerate()で回して、添字と値をタプル?でとりだしてます。添字を見ながら1文字取り出すのか、2文字取り出すのかの判断が必要だからです。あとは一緒ですね。1文字取り出すときは、.first()を使って見ました。 実は、2文字取り出す時と、1文字の時と同じロジック使った方が共通化できて、短くなった???

ということで、こんな感じでした。いつものようにツッコミお待ちしてます。

所感

問題それぞれについてではなく、 やってて思ったのですが、問題に対して想定される結果が記載されていると嬉しいなと思いました。 ロジックについては、各自実装者に寄ったり、言語によって違いが出たりするし、議論するベースになっていいかなと思うんですが、 問題で想定されている結果(出力)があると、自分の実装にケアが足りないところがないのか?とか、ケアしなくていい点とかがわかるのかもなぁと。 ユニットテスト相当のものがあると楽かなぁと。

このケースどうするんだろ?みたいなのが、ところどころコメントに残ったりしてます。 出題の意図としては、その部分も議論の対象ということなのかな?

Comments