2

「ab」と「cdabd」などの文字列を指定すると、これらの2つの文字列で使用されると「cd」を出力する関数を作成したい

私は今までこれを持っています

takeUntil :: String -> String -> String
takeUntil [] [] = []
takeUntil xs [] = []
takeUntil [] ys = []
takeUntil xs ys = if contains xs ys then -- ???? I get stuck here. 

含まれる関数は、以前に定義した関数です (この関数全体は大文字と小文字を区別しない必要があります)。

contains :: String -> String -> Bool
contains _ [] = True
contains [] _ = False
contains xs ys = isPrefixOf (map toLower ys) (map toLower xs) || contains (tail(map toLower xs)      (map toLower ys)
4

2 に答える 2

3

これを行うには多くの方法がありますが、パスを続行して、次のことを試してください。

import Data.List

takeUntil :: String -> String -> String
takeUntil [] [] = []                           --don't need this
takeUntil xs [] = [] 
takeUntil [] ys = [] 
takeUntil xs (y:ys) = if   isPrefixOf xs (y:ys)
                      then []
                      else y:(takeUntil xs (tail (y:ys)))

いくつかの出力:

takeUntil "ab" "cdabd"
"cd"

takeUntil "b" "cdabd"
"cda"

takeUntil "d" "cdabd"
"c"

takeUntil "c" "cdabd"
""

takeUntil "xxx" "cdabd"
"cdabd"

編集:

OPは、関数が大文字と小文字を区別しないことを望んでいます。

繰り返しますが、多くの方法でそれを行うことができます。たとえば、次のlowerCaseような関数を書くことができます (すでに にあると思いますData.Text):

import qualified Data.Char as Char

lowerCase :: String -> String
lowerCase [] = []
lowerCase (x:xs) = (Char.toLower x):(lowerCase xs)

そして、それを次のように使用します(おそらく醜く、あまり実用的ではありません):

takeUntil (lowerCase "cd") (lowerCase "abcDe")
"ab"

それはあなたが期待する結果です。

lowerCaseまた、その関数を内部で使用できますtakeUntil

-- ...
takeUntil xs (y:ys) = if  isPrefixOf (lowerCase xs) (lowerCase (y:ys))
-- ...

したがって、次のことができます。

takeUntil "cd" "abcDe"
"ab"

とにかく、最良の選択肢は@bheklilrが提案したものだと思います。独自のisPrefixOfCaseless関数を作成します。

これが役立つことを願っています。

于 2014-10-23T14:16:01.760 に答える
0

を定義するための多数のアプローチの中で、次のようにData.Text関数をtakeUntil使用することを検討してください。

takeUntil :: String -> String -> String
takeUntil sep txt =  unpack $ fst $ breakOn (pack sep) (toCaseFold $ pack txt)

は aを aにpack変換しますが、逆は行います。大文字と小文字を区別しない操作用。最初の (可能な) 一致まで、最初の要素にテキストが含まれるペアを配信します。StringTextuncpaktoCaseFoldbreakOn

アップデート

Stringこのアプローチは、すでに提案されているテストをカバーしますが、たとえばここではオリジナルを保持しません。

takeUntil "e" "abcDe"
"abcd"

これを回避するには、たとえば、ブレーク ポイントでのインデックスによる分割が必要です。

于 2014-10-24T06:55:46.717 に答える