2011-06-13 10 views
6

Data/ByteString.hs kaynağında findSubstrings işlevinin breakSubstring lehine reddedildiğini belirtir. Ancak KMP algoritması kullanılarak uygulanan findSubstrings'un, naif olan breakSubstring'da kullanılan algoritmadan çok daha verimli olduğunu düşünüyorum. Bunun neden yapıldığına dair bir fikri olan var mı?findSubstrings ve breakSubstring içinde Data.ByteString

İşte eski uygulama görebilirsiniz:

{-# DEPRECATED findSubstrings "findSubstrings is deprecated in favour of breakSubstring." #-} 

{- 
{- This function uses the Knuth-Morris-Pratt string matching algorithm. -} 

findSubstrings [email protected](PS _ _ m) [email protected](PS _ _ n) = search 0 0 
where 
    patc x = pat `unsafeIndex` x 
    strc x = str `unsafeIndex` x 

    -- maybe we should make kmpNext a UArray before using it in search? 
    kmpNext = listArray (0,m) (-1:kmpNextL pat (-1)) 
    kmpNextL p _ | null p = [] 
    kmpNextL p j = let j' = next (unsafeHead p) j + 1 
        ps = unsafeTail p 
        x = if not (null ps) && unsafeHead ps == patc j' 
          then kmpNext Array.! j' else j' 
        in x:kmpNextL ps j' 
    search i j = match ++ rest -- i: position in string, j: position in pattern 
    where match = if j == m then [(i - j)] else [] 
      rest = if i == n then [] else search (i+1) (next (strc i) j + 1) 
    next c j | j >= 0 && (j == m || c /= patc j) = next c (kmpNext Array.! j) 
      | otherwise = j 
-} 

Ve burada yeni naif bir: değişim için

findSubstrings :: ByteString --^String to search for. 
      -> ByteString --^String to seach in. 
      -> [Int] 
findSubstrings pat str 
    | null pat   = [0 .. length str] 
    | otherwise  = search 0 str 
where 
    STRICT2(search) 
    search n s 
     | null s    = [] 
     | pat `isPrefixOf` s = n : search (n+1) (unsafeTail s) 
     | otherwise   =  search (n+1) (unsafeTail s) 

cevap

4

nedeni KMP uygulanması aslında naif sürümden daha verimsiz olmasıydı, performansa bir gözle uygulanmaktadır.

+0

KMP zaman karmaşıklığı açısından daha iyi değil mi? – sob7y

+2

Bu teorik olarak. Pratikte, bu uygulamanın, yürüttüğüm tüm testlerde naif versiyona çok fazla verimsiz olduğunu söylüyorum. –

İlgili konular