@johtaniの日記 2nd

@johtani ‘s blog 2nd edition

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

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

05. n-gram

問題はこちら

みんな大好きn-gramです。単語と文字があるので、それぞれ別関数として実装しました。問題はbi-gramとn=2だったのですが、一応、nを引数に取る形にして実装しました。

まずは、単語です。

前に実装した時は、自分で頑張って、先頭から数えたりしてたんですが、Rustにはwindows(n)という便利なメソッドがsliceにあり、これを利用したらこんな簡単になりました。 sliceは特定のシーケンス(配列)に対してある特定のサイズのViewを作ってくれます(説明あってる?)。 ということで、文字列から、単語の配列(スペース区切りで単語にしている)を作り出して、windows(n)メソッドを通すと、 nで指定した数字の個数だけの単語の配列を先頭から、1単語ずつずらして作ってくれます。まさに、n-gram! 戻り値は配列の配列です。 1点だけ疑問点があるのは、「空白で区切ったものが単語」という考え方で良いかどうか?という点です。特に問題文にはそれが明示されていなかったので、このような前提を置いてあります。

invalid_n(text, n)nの値や入力された文字列をチェックする関数です。入力チェックですね。nが1よりも小さい場合、入力文字列が空文字の場合は、warningでメッセージを出して、空の配列を返す仕組みになっています。

次は、文字です。

単語とほぼ一緒ですが、入力文字列を、1文字ずつの配列にしているところが異なります。 また、windowsメソッドで取り出された、1文字ずつのn個の配列を文字列に修正してから、結果の配列に入れています。 ここでも疑問は空白をどう扱うか?になります。 現時点では、空白も1文字とカウントして扱うことにしてあります。 どっちがいいのかなぁ?

06. 集合

問題はこちら

まずは、文字n-gramで出てきた文字列をSetに入れる関数から。

n-gramの問題で実装した文字n-gramの関数の戻り値を配列ではなく、BTreeSetに変えたものになります。比較などがしやすいように?と思い、BTreeSetを利用していますが、実装としてはHashSetでも問題ないかと。 この関数の集合(Set)を元に、和集合、積集合、差集合を求める関数を実装しました。

Setのメソッドとして、それぞれ、union=和集合、intersection=積集合、difference=差集合のメソッドが用意されているので、特に困ることはなかったです。 差集合については、1-2と2-1で結果が異なるはずなので、それぞれをテストケース、main.rsで出力するようにしてあります。

所感

今回は、Rustがすでに実装してくれているメソッドがあったので楽ができました。 やりたいことに相当するメソッドがあるかどうかを調べるためにリファレンスを探さないといけないのがちょっと苦労しましたが。。。 ということで、今日はこの辺りまで。

Comments