我正在尝试匹配字典中的单词,不区分大小写。我的初步方法 看起来像这样:
有更好(更有效)的方法来实现这一目标吗?我是Haskell的新手。
import System.IO
import Data.Text (toLower, pack, unpack)
import Data.Set (fromList, member)
main = do
let path = "/usr/share/dict/american-english"
h <- openFile path ReadMode
hSetEncoding h utf8
contents <- hGetContents h
let mySet = (fromList . map (unpack . toLower . pack) . lines) contents
putStrLn $ show $ member "acadia" mySet
答案 0 :(得分:7)
我只是直接使用Text
而不是转换为/来自Strings。
Data.Text.IO
包含hGetContents
,readFile
等版本,用于从文件中读取文本,Data.Text
包含lines
文本。
{-# LANGUAGE OverloadedStrings #-}
import System.IO
import qualified Data.Text as T
import qualified Data.Text.IO as T
import qualified Data.Set as S
main = do
let path = "/usr/share/dict/american-english"
h <- openFile path ReadMode
hSetEncoding h utf8
contents <- T.hGetContents h
let mySet = (S.fromList . map T.toLower . T.lines) contents
putStrLn $ show $ S.member "acadia" mySet
通过使用T.tolower
和T.lines
,我们避免显式打包/解包。
mySet
现在是一组Text值而不是字符串。通过使用
OverloadedStrings pragma将解释文字"acadia"
作为文本值。
答案 1 :(得分:2)
是的,你的建议是合理的。一些评论,主要与主要问题无关:
Text
而不是String
会更有效。toCaseFold
功能toLower
,这种情况更合适。答案 2 :(得分:1)
即使您发现我的第一个回答有帮助,让我提出另一种方法......
我写的一个boggle求解器只是在整个字典中读取一个ByteString,并且查找单词在该ByteString上执行二进制搜索。
字典必须已按排序顺序排列并标准化为小写,但通常这不是问题,因为字典是静态的 并提前知道。
当然,当您在执行二进制搜索时计算(lo+hi)/2
时,您可能会在单词的中间位置,因此您只需备份到当前单词的开头。
这样做的主要优点是加载字典非常快,而且内存效率很高。此外,搜索算法具有良好的内存局部性。我没有测量过,但如果创建一个Data.Set
将比原始数据的大小增加一倍,我不会感到惊讶。
代码可在此处找到:https://github.com/erantapaa/hoggle