一个Haskell程序,使用Head和Tail来关联2个字符串

时间:2011-06-09 12:14:07

标签: haskell

我需要确定字符串是否是另一个字符串的子字符串。 我认为是将一个字符串的头部与头部和另一个字符串进行比较,然后再与尾部的头部进行比较等等。但是我需要将相关子字符串的每个元素与另一个字符串进行比较,然后我认为是必要的借助功能图。但我不知道如何编写程序。

3 个答案:

答案 0 :(得分:4)

使用Data.List.isInfixOf

import Data.List (isInfixOf)
import System (getArgs)

main = do [needle, haystack] <- getArgs
          if needle `isInfixOf` haystack
            then putStrLn $ concat [show needle, " is in ", show haystack]
            else putStrLn $ concat [show needle, " is NOT in ", show haystack]

“子串”并不代表您认为的含义。因此,混乱。这样做你想要的吗?

import Data.List (all)

someFunction :: [a] -> [a] -> Bool
someFunction needle haystack = all (`elem` haystack) needle

main = do [needle, haystack] <- getArgs
          if needle `someFunction` haystack
            then putStrLn $ concat [show needle, " is in ", show haystack]
            else putStrLn $ concat [show needle, " is NOT in ", show haystack]

我仍然不确定这是否是你想要的。

您希望"cc" `someFunction` "abcde"返回True(因为'c'位于"abcde"中)还是False(因为'c'仅位于"abcde"一次)?< / p>

您是否希望"db" `someFunction` "abcde"返回(因为'd''b'都在"abcde")或False(因为它们没有按此顺序出现)?

答案 1 :(得分:0)

如果您正在尝试实施subString功能,那么这是我的尝试:

subString :: String -> String -> Bool
subString xs [] = True
subString [] _ = False
subString (x:xs) (y:ys)
  | x == y = ys == take (length ys) xs
  | otherwise = subString xs (y:ys)

示例:

*Main> subString "MarcoS" "arc"
True
*Main> subString "MarcoS" "marc"
False
*Main> subString "MarcoS" ""
True
*Main> subString "" "a"
False

我意识到这不是使用headtail,但我就是这样做的。


修改

在查看source code for isInfixOf之后(正如dave4420所建议的那样),我意识到使用tails有一种简洁的方式和更一般的方法......一个永远不会停止学习:)


修改2

从评论我明白,问题实际上要求检查字符串是否包含任何顺序的另一个字符串的所有字母,或者更一般地,如果元素列表包含任何顺序的另一个列表的所有元素。所以,这是我的实现:

import Data.List

-- does xs containsAll ys? containsAll xs ys
containsAll :: (Eq a) => [a] -> [a] -> Bool
containsAll _ [] = True
containsAll [] _ = False
containsAll xs ys = elem ys $ concatMap (permutations) (subsequences xs)

示例:

*Main> containsAll "pippo" "pppp"
False
*Main> containsAll "pippo" "ppp"
True
*Main> containsAll "pippo" "ppi"
True
*Main> containsAll "pippo" "ipp"
True

可能还有其他(更好)的方式,我很想知道:)


编辑3

从其他评论中我了解到问题本质上是子集检查,即检查字符串的所有字母是否也在另一个字符串中。所以,这是一种方法:

-- are all xs in ys? allin xs ys
allIn :: (Eq a) => [a] -> [a] -> Bool
allIn xs ys = and $ map (flip elem ys) xs

或者,可以使用Data.Set来表示:

import Data.Set

allIn :: (Ord a) => [a] -> [a] -> Bool
allIn xs ys = (fromList xs) `isSubsetOf` (fromList ys)

示例:

*Main Data.Set> "ppp" `allIn` "pippo"
True
*Main Data.Set> "ipp" `allIn` "pippo"
True
*Main Data.Set> "pppp" `allIn` "pippo"
True

答案 2 :(得分:0)

也许您会对(\\)中提供的Data.List功能感兴趣。