BiGram の実装

This entry was posted by on Saturday, 25 June, 2005
>これは話を振られたのかな?(笑) > >OCaml の場合に、関数的に書くのに拘りがなければ、次のように書くのがたぶん一番速い。 > >(* bigram : string -> (char * char, int) Hashtbl.t *)
let bigram s =
let h = Hashtbl.create (String.length s) in
for i = 0 to String.length s - 2 do
let c = s.[i], s[i+1] in
if Hashtbl.mem h c then
Hashtbl.replace h c (Hashtbl.find h c + 1)
else
Hashtbl.add h c 1
done;
h

let _ =
let h = bigram Sys.argv.(0) in
Hashtbl.iter (fun (c1, c2) v -> Printf.printf "(%c, %c)\t%d\n" c1 c2 v) h > >「for って……」というのは禁句(笑)。関数的に書くとしても、↑の繰返しを末尾再帰で書くくらいかなという気が。綺麗じゃないなあ。これは、文字列型がリストでも配列でもない独自の型であり、相互に変換する関数が(実は)用意されていない、ということにある気がします。や、作るのは簡単ですし >ExtLib > とかを使えば標準で備わっているんですが。 > >でまぁ他には、というと、うーん、個人的には fold が好きなので、 fold を使うかなぁ。 > >open ExtString

let bigram s =
let h = Hashtbl.create (String.length s) in
snd
(String.fold_left
(function
| (Some c1, h) c2 ->
if Hashtbl.mem h (c1, c2) then
Hashtbl.replace h (c1, c2) (Hashtbl.find h (c1, c2) + 1)
else
Hashtbl.add h (c1, c2) 1;
(Some c2, h)
| (None, h) c2 -> (Some c2, h))
s) > >うーん無理矢理。これは「普通」ではないです。たぶん。でもって String.fold 系も標準じゃないから ExtLib を入れないと無理。 > >結論的には、 OCaml では「関数的に書くと遅い上に書きづらい」という悩みがあったりする悪寒。ストリームパーサが使えそうで微妙に使えないあたりも腹立たしい。 > >拙作の LazyList を使えばもう少しマシになるでしょうが「リストから数を数えながらハッシュを構成」する部分はこれ以上の書きようはないので仕方ないところですね。 ((x -> >

Comments are closed.