#/*********************************************************** # sboymoo.rb -- Boyer--Moore法 #***********************************************************/ # 簡略Boyer-Moore法 UCHAR_MAX = 255 DEMO = true # デモンストレーション def position(text, pattern) $skip = [] len = pattern.length # 文字列の長さ if (len == 0); return -1; end # エラー: 長さ0 tail = pattern[len - 1] # 最後の文字 if (len == 1) # 長さ1なら簡単! i = 0; while (text[i] != nil) if (text[i] == tail); return i; end i += 1; end else # 長さ2以上なら表を作って… for i in 0..UCHAR_MAX; $skip[i] = len; end for i in 0...len - 1 $skip[pattern[i]] = len - 1 - i end i = len - 1 # いよいよ照合 while ((c = text[i]) != nil) if DEMO == true # デモンストレーション用 printf("テ: %s\n", text) printf("照: %*s\n", i + 1, pattern) end if (c == tail) j = len - 1; k = i while (pattern[j -= 1] == text[k -= 1]) if (j == 0); return k; end # 見つかった end end i += $skip[c] end end return -1; # 見つからなかった end def mygets(n) # n 文字まで s に読み込む s = gets if (s == nil || s == "\n") return nil else return (s.chomp)[0..n] end end text = "supercalifragilisticexpialidocious" pattern = "" while (true) printf("テキスト文字列 (リターン: %s)\n ? ", text) if (s = mygets(127)) != nil text = s end printf("照合文字列 (リターン: 終了)\n ? ") if (s = mygets(127)) != nil pattern = s else break end p = position(text, pattern) if (p >= 0); printf("位置 = %d\n\n", p) else; printf("見つかりません.\n\n") end end exit 0