Iconミニ講座7(曖昧参照)
はじめると、止まらないエビセン体質のため、ついついミニ講座の続きを考えて
しまいます。 曖昧検索を入れてみました。
コマンドラインから、英文文字列を指定して辞書検索を行いますが、'.'をワイルド
カード (a-z)と見なせるようにしてみました。
'.'が2文字以上の場合は、"ab"と "ba"のようなものは、別に検索しないように
細工を入れました。
-----^ DICREFP2.ICN ( date:03-08-23 time:21:51 ) -----------<cut here
####################
# 辞書読込・使用文字種毎の分類をした辞書参照で、曖昧検索対応。
####################
# dicrep2.icn Rev.1.0 2003/08/23 windy 風つかい H.S.
####################
# Usage dicrefp2 英文字列(.はワイルドカード)
# english.dicは、スペルチェック用の英単語が順に並んだもの。
# このプログラムのテストでは、DD SOFT SoundMixSpellコンポーネント
# Ver 0.3.0 に 同梱の辞書ファイルを使用。
# This file is in the public domain.
procedure main(args)
# コマンドライン引数チェック。無ければ Usage表示
if *args < 1 then stop("dicrefp2 英単語 ( . はワイルドカード)")
# 辞書読込
dic := "english.dic" # 辞書ファイル名
dir := open(dic) | stop(dic," が見つかりません") # 辞書ファイルオープン
S_dic := set() # 辞書ダブリチェック用 set生成
T_dic := table() # 辞書格納 table生成
write(dic," を読込中です。") # 辞書読み込み
write("開始:",&clock)
n := 0 # 辞書行数カウンタ
while word := read(dir) do { # 辞書を1行ずつ読み込んで、
n +:= 1
if n % 1000 = 0 then writes(&errout,"*") # 読み込み状況表示
if member(S_dic,word) then writes(&errout,"?") # 登録済みならエラー表示
else {
insert(S_dic,word) # setに登録
# 単語を小文字変換しソートしたものをインデックスにして格納
# 同一文字を含む単語は同じインデックスに listの要素として格納される。
# ↓文字列ソート
s_word := csort(map(word)) # 小文字へ変換し、ソートして
# ↑小文字変換
if member(T_dic,s_word) # 辞書テーブルにあるかチェック
then put(T_dic[s_word], word) # あれば、その listに追加
else T_dic[s_word] := [word] # 無ければ、listに入れて登録
}
}
close(dir) # 辞書ファイルクローズ
write(&errout)
write("終了:",&clock)
write(dic," の読込を終わりました。 ",*S_dic," 語ありました。")
write("同一文字で構\成される単語をまとめると、",*T_dic," 種類となります。")
# ↑Shift-JISでは、0x5cを含むので、"\"を補完。
# 辞書参照テスト
# コマンドラインの引数にて、辞書を参照
c_word := args[1]
s_word := deletec(c_word,'.') # コマンドライン文字列から '.'を削除
n := *c_word -*s_word # '.'の数
n_comb := 0 # 組合せ数カウンタ
n_find := 0 # 辞書にある件数カウンタ
write(c_word," の組合せが辞書にあるかチェック中です。")
write("開始:",&clock)
every s := mscombd(string(&lcase),n) do { # ワイルドカード対応文字を取り出し
n_comb +:= 1 # 組合せ数カウンタ+1
ss := csort(map(s || s_word)) # コマンドライン引数の '.'以外の部分に足し
# 小文字変換し、ソートして
if member(T_dic,ss) # 辞書にあれば
then {
n_find +:= 1 # 辞書にある件数カウンタ+1
writes(&errout,"!") # 発見表示
writes(ss,": ") # 変換前のデータを書き出し
every writes(" ",!T_dic[ss]) # 辞書内容を書き出す
write()
}
}
write(&errout)
write("終了:",&clock)
write(n_comb," 通りの組合せのうち、",n_find," 通りが辞書にありました。")
end
#############################
# 文字列から重複して、n個、降順のものを取り出す generator
#############################
# arg [1]: string
# [2]: integer
# value : string
# Usage : every ss := mscombd(s,n) do ..
# ("abc",2) -> "aa","ab","ac","bb","bc","cc"
procedure mscombd(s,n)
if n =0 then return "" # 再帰終了
every i := 1 to *s do { # 1〜文字列長まで
# ↓ i番目の文字を取り出して
suspend s[i] || mscombd(s[i:0],n-1)
} # ↑それ以降の文字と組み合わせる
end
# BIPL(Icon基本ライブラリー)より
####################
# strings.icnに含まれる 文字のソート procedure
####################
procedure csort(s) #: lexically ordered characters
local c, s1 # ローカル変数宣言(無くても良い)
s1 := "" # 初期値クリア
every c := !cset(s) do # 引数を cset(文字集合)へ変換し順に取り出す。
every find(c, s) do # 取り出した文字で、引数文字列を検索し、
s1 ||:= c # 見つかる度に、文字を s1に足し込む。
return s1
end
# csetから !で要素を取り出す時には、アルファベット順に取り出せる。
####################
# strings.icnに含まれる 文字の削除 procedure
####################
procedure deletec(s, c) #: delete characters
local result # ローカル宣言(無くても良い)
result := "" # 削除後の文字列格納エリア
s ? { # sを走査対象として、
while result ||:= tab(upto(c)) do # cが見つかる迄の文字列を足し込んで
tab(many(c)) # c以外の文字までスキップ
return result ||:= tab(0) # 余りの文字を足し込む
}
end
-----$ DICREFP2.ICN ( lines:123 words:404 ) ----------------<cut here
dicrefp2 sunris. >ggg と、ワイルドカードを 1ついれた場合は
こんな結果になります。
-----^ GGG ( date:03-08-23 time:21:52 ) --------------------<cut here
english.dic を読込中です。
開始:21:51:57
終了:21:52:40
english.dic の読込を終わりました。 257650 語ありました。
同一文字で構成される単語をまとめると、223704 種類となります。
sunris. の組合せが辞書にあるかチェック中です。
開始:21:52:40
ainrssu: Russian Surnias
dinrssu: sundris
einrssu: insures Serinus sunrise
終了:21:52:40
26 通りの組合せのうち、3 通りが辞書にありました。
-----$ GGG ( lines:12 words:25 ) ---------------------------<cut here
風つかい(hshinoh@...)
IconのWWWは、 http://www.cs.arizona.edu/icon/
UniconのWWWは、http://unicon.sourceforge.net/index.html
BGM: 日本組曲 / 有馬徹とノーチェ・クバーナ with 杉本喜代志