3

文字列を文字列でフィルタリングしたい。私が望むのは、最初に発生するすべての文字を削除することです。

myFunc :: String -> String -> String

お気に入り:

myFunc "dddog" "bigdddddog" = "biddg"

"dddog": 3x d、1x o、1x g

2 番目の文字列では、3x d、1x o、および 1x g が削除されたため、出力は次のようになります。biddg

発生するすべての文字が削除されるため、フィルターを使用できません。そして、私はそれで長い間苦労しました。

前もって感謝します:)

4

7 に答える 7

1

モナドの解決策はまだありません。

import Control.Monad.State

myFunc :: String -> State String String
myFunc [] = return ""
myFunc (x:xs) = get >>= f where
  f [] = return (x:xs)
  f (y:ys) = if y == x then put ys >> myFunc xs
             else myFunc xs >>= return . (x:)

main = do
      let (a,b) = runState (myFunc "bigdddddog") "dddog" in
        putStr a
于 2013-07-16T05:10:58.583 に答える
1

私はカーンのエレガントなソリューションが好きです。これを意味する場合...これは、全体として一致した場合にのみ「ddd」が削除されるものです。

import Data.List (group,isPrefixOf,delete)

f needles str = g (group needles) str where
  g needles []         = []
  g needles xxs@(x:xs)
    | null needle' = [x] ++ g needles xs
    | otherwise    = let needle = head needle'
                     in g (delete needle needles) (drop (length needle) xxs)
   where needle' = dropWhile (not . flip isPrefixOf xxs) needles

出力:

*Main> f "dddog" "bigdddddog"
"biddg"

*Main> f "dddog" "bdigdogd"
"bdidgd"
于 2013-07-16T02:42:29.670 に答える
0

Data.List の定義済み関数を使用して、

-- mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
-- lookup :: (Eq a) => a -> [(a, b)] -> Maybe b

{-# LANGUAGE PatternGuards #-}
import Data.List

picks []     = []       -- http://stackoverflow.com/a/9889702/849891
picks (x:xs) = (x,xs) : [ (y,x:ys) | (y,ys) <- picks xs]

myFunc a b = concat . snd $ mapAccumL f (picks a) b
  where
    f acc x | Just r <- lookup x acc = (picks r,[])
    f acc x = (acc,[x])

テスト:

Prelude Data.List> myFunc "dddog" "bigdddddog"
"biddg"

編集:これはもちろん、よりも少し複雑です(\\)。イラストとして置いておきます。明らかdelete(\\) = foldl (flip delete).

于 2013-07-15T21:58:01.593 に答える