2016-09-02 54 views
1

我試圖從字典中匹配不區分大小寫的字。我最初的做法 看起來像這樣:大字典字集的大小寫轉換

  1. read dict;將所有單詞轉換爲小寫,存儲在集合中。在集

會員

  • 檢查新詞有沒有更好的(更有效)的方式來實現這一目標?我是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

    該方法對我來說很好。也許對於字符串,有一些優化的trie軟件包在hackage上,但這已經很好了。 – chi

    回答

    7

    我只是直接與Text一起工作,而不是從字符串轉換到字符串。

    Data.Text.IO包含hGetContentsreadFile等版本從文件中讀取文本,並Data.Textlines文本。

    {-# 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.tolowerT.lines我們避免了明確的包/解包的電話。

    mySet現在是一組文本值而不是字符串。通過使用 OverloadedStrings編譯指示,文字"acadia"將被解釋爲 作爲文本值。

    2

    是的,你提出的是合理的。一些幾句話,大部分是無關的主要問題:

    1. 這將是更有效地限制你自己只使用Text而不是String
    2. 首選toCaseFold功能爲toLower,這種情況更適合。
    1

    即使你找到了我的第一個答案有幫助,讓我提出另一種方法......

    一個驚奇求解我寫只是讀取整個字典作爲單個字節字符串,並查找單詞執行在該ByteString上進行二進制搜索。

    該字典必須已排序並標準化爲小寫,但通常這不是一個問題,因爲字典是靜態的,並且事先已知的 。

    當然,當計算(lo+hi)/2執行二進制搜索時,您可能會落在詞的中間,因此您只需備份到當前詞的開頭。

    這樣做的主要優點是加載字典速度非常快,而且內存效率很高。而且,搜索算法具有良好的存儲局部性。我還沒有測量過,但如果創建一個Data.Set將使原始數據的尺寸增加一倍以上,我不會感到驚訝。

    該代碼在這裏可用:https://github.com/erantapaa/hoggle