有没有更好的方法来编写“字符串包含X”方法?

时间:2012-01-05 19:40:02

标签: haskell recursion pattern-matching

只是盯着使用Haskell并实现(据我所知),没有直接的方法来检查字符串,看它是否包含一个较小的字符串。所以我想我只是试一试。

基本上,我们的想法是检查两个字符串是否大小相同并且相等。如果检查的字符串更长,则递归地删除头部并再次运行检查,直到检查的字符串长度相同。

其余的可能性我使用模式匹配来处理它们。这就是我想出的:

stringExists "" wordToCheckAgainst = False
stringExists wordToCheckFor "" = False
stringExists wordToCheckFor wordToCheckAgainst | length wordToCheckAgainst < length wordToCheckFor = False
                                               | length wordToCheckAgainst == length wordToCheckFor = wordToCheckAgainst == wordToCheckFor
                                               | take (length wordToCheckFor) wordToCheckAgainst == wordToCheckFor = True
                                               | otherwise = stringExists wordToCheckFor (tail wordToCheckAgainst)

3 个答案:

答案 0 :(得分:45)

如果您在Hoogle搜索您要查找的功能的签名(String -> String -> Bool),您应该会在最佳结果中看到isInfixOf

答案 1 :(得分:24)

来自Data.List的{​​p> isInfixOf肯定会解决问题,但是如果干草堆较长或针脚不正确,你应该考虑更高级的string matching algorithms,其平均和最差情况要好得多。< / p>

¹考虑一个非常长的字符串,该字符串仅包含a和一个开头有很多a的针,最后一个b

答案 2 :(得分:9)

考虑使用text package(Hackage上的text,现在也是Haskell平台的一部分)来满足您的文本处理需求。它提供了Unicode文本类型,比基于内置列表的String更节省时间和空间。对于字符串搜索,textimplements一个Boyer-Moore-based algorithm,其复杂度高于Data.List.isInfixOf使用的天真方法。

用法示例:

Prelude> :s -XOverloadedStrings
Prelude> import qualified Data.Text as T
Prelude Data.Text> T.breakOnAll "abc" "defabcged"
[("def","abcged")]
Prelude Data.Text> T.isInfixOf "abc" "defabcged"
True