はじめに
- Haskellの勉強のためにBWT(Burrows-Wheeler Transform)を書いてみました。
BWT(および逆変換)
- Qiita上にもわかりやすい説明がいっぱいあるので省略。
使い方
-
下記のソースコードのusageおよび使用例のように使用してください。
-
bwtで変換する文字列に"$"は使用できません(コマンドの内部で、文字列の終端として"$"を付与してるので)。
-
Haskellの勉強のために、(ちょっと無理やりですが)モナドを使用して結果がMaybe Stringとして返ってきます。
【実装】
{- BWT変換(Burrows-Wheeler-Transform) usage: > bwt <String> > invBwt <String> 使用条件: ・"$"を文字列の終わりとして使用しているので、"$"を含む文字列には 使用できない。 使用例: > bwt "mississippi" Just "ipssm$pissii" > bwt "mississippi" >>= invBwt Just "mississippi" > bwt "mississippi$" >>= invBwt Nothing -} module Bwt where import Data.List -- BWT変換 getSA :: Ord a => [a] -> [Int] getSA str = map snd $ sort $ map (\n -> (drop n str, n)) [0..(length(str)-1)] bwt' :: Ord a => [a] -> [a] bwt' str = map (\sa -> str!!(mod (sa-1) $ length(str))) $ getSA str bwt :: String -> Maybe String bwt str = if checkInput then Just (bwt' (str ++ "$")) else Nothing where checkInput = not $ elem '$' str -- BWT逆変換 lfm :: Ord a => [a] -> [Int] lfm str = map snd $ sort $ zip str [0..] invBwt' :: Ord a => [a] -> Int -> [a] invBwt' str n = map (str!!) . take (length str) . tail $ iterate ((lfm str)!!) n invBwt :: String -> Maybe String invBwt str = if checkInput then Just (init (invBwt' str endPoint)) else Nothing where checkInput = elem '$' str endPoint = length $ takeWhile (/='$') str
使用した環境
- ghci: version 8.8.3
2020/09/18 初稿: