4

フラット文字列とリストの置換のために 3 つの関数を作成する必要があります。

他の言語のような置換機能があるかどうかはわかりません。私はそれを検索しましたが、残念ながら成功しませんでした:-(

だから私の試みはまだかなり薄いです。

第 1 関数:

replace  ::  String  ->  String  ->  String  ->  String
replace findStr replaceStr myText = replace()??

最初の関数に対する私のアプローチ:

replace :: String -> String -> String -> String
replace [] old new = []

replace str old new = loop str
  where
    loop [] = []
    loop str =
      let (prefix, rest) = splitAt n str
      in
        if old == prefix                -- found an occurrence?
        then new ++ loop rest           -- yes: replace

        else head str : loop (tail str) -- no: keep looking
    n = length old  

2番目の機能:

replaceBasedIdx ::  String  ->  [String]  ->  String  ->  String
replaceBasedIdx findStr replaceStrList myText = replace()???

この関数は、myTxt の 1 番目の findStr を replaceStrList の 1 番目の要素に、2 番目の findStr を 2 番目の要素に、というように置き換える必要があります。

例:

replaceBasedIdx   "a"  ["G","V","X"]  "Haskell is a language"
"HGskell is V lXnguage"

2番目の機能に対する私のアプローチ:

replaceBasedIdx    ::  String  ->  [String]  ->  String  ->  String
replaceBasedIdx    findStr replaceStrList myText = replaceBasedIdxSub findStr replaceStrList myText 0

replaceBasedIdxSub  ::  String  ->  [String]  ->  String  -> Int -> String
replaceBasedIdxSub findStr replaceStrList myText counter = loop myText
  where
    loop [] = []
    loop myText =
      let (prefix, rest) = splitAt n myText
      in
        if findStr == prefix                                -- found an occurrence?
        then (replaceStrList !! (counter+1)) ++ loop rest   -- yes: replace it

        else head myText : loop (tail myText)               -- no: keep looking
    n = length findStr

最終結果に非常に近づいていますが、カウンターは増加しません。

私の間違いがどこにあるのか教えてください。また、1 番目または 2 番目の関数を変更して 3 番目の関数を取得するにはどうすればよいですか?

3番目の機能:

replaceBasedIdxMultiple  ::  [String]  ->  [String]  ->  String  ->  String
replaceBasedIdxMultiple  findStrList replaceStrList myText = replace()???

この関数は、myTxt の findStrList の各要素を replaceStrList の対応する要素に置き換える必要があるため、1. を 1. に、2. を 2. に、というように...

例:

replaceBasedIdxMultiple ["A","X","G"] ["N","Y","K"]  "ABXMG"
"NBYMK"

これで私を助けてもらえますか?いくつかのヒントとヒント、それを始める方法は?

私は本当にバラバラです:-(

事前にどうもありがとう

よろしくお願いします!

4

2 に答える 2

6

パッケージData.List.Utilsの一部に存在しMissingHます。

実際、これは非常に簡潔な実装です。

replace :: Eq a => [a] -> [a] -> [a] -> [a]
replace old new = join new . split old
于 2013-05-07T23:35:02.363 に答える
1

まず第一に、それはすでに標準の関数であるjoinため、悪い名前です。また、この関数をこのように定義する理由もわかりません。あまり役に立たないようです。

しかし、わかりました、あなたは何かを試しました。それでは、適切な解決策を見つけてみましょう...

Haskell では通常は良いアイデアであるため、これを下位の問題に分割したいと考えています。最初に必要なのは、置換したい部分文字列を見つけることです。これは次のようになります

locateSub :: (Eq a) =>
        [a]             -- ^ The sought sublist.
     -> [a]             -- ^ The source list.
     -> Maybe ([a],[a]) -- ^ Everything to the left and, if found, everything
                        -- to the right of the sought sublist. No need to return
                        -- the sublist itself in between since we already know it!

この関数を使用すると、replace簡単です。

replace oldSub newSub list
    = case locateSub oldSub list of
        Nothing -> list   -- Sublist not found: we're done already!
        Just (l, r) -> l ++ newSub ++ replace oldSub newSub r

replaceBasedIdxnewSubs のリストを常にそのまま渡すのではなく、再帰するだけで済みます。

したがって、あなたがする必要があるのは実装locateSubです。あなたisPrefixOfはすでに正しい軌道に乗っています。実際、それはあなたのように見えます_replace(ところで、Haskell'では、関数の「ローカルバリアント/ヘルパー」に名前を付けるためにアンダースコアではなくプライムを使用するのが慣例であるため、 replace'.

于 2013-05-07T20:36:04.667 に答える