Haskellを使って見つめただけで、(私が知る限り)文字列をチェックして小さな文字列が含まれているかどうかを直接確認する方法がないことに気づきました。だから私はそれを撃つだけだと思いました。
基本的に、2つの文字列が同じサイズで、等しいかどうかを確認するというアイデアでした。チェック対象の文字列が長かった場合は、再帰的に頭を下げて、チェック対象の文字列が同じ長さになるまでチェックを再実行してください。
残りの可能性は、パターンマッチングを使用して処理しました。これは私が思いついたものです:
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)
isInfixOf
from Data.List
は確かに問題を解決しますが、干し草の山や逆針が長い場合は、より高度な 文字列照合アルゴリズム を検討する必要があります。平均と最悪の場合の複雑さははるかに優れています。
¹a
と、最初にたくさんのa
があり、最後に1つのb
がある針だけで構成される非常に長い文字列について考えてみます。
テキスト処理のニーズに text
package (text
on Hackage、現在はHaskell Platformの一部)を使用することを検討してください。 Unicodeテキストタイプを提供します。これは、組み込みのリストベースのString
よりも時間とスペースの効率が高くなります。文字列検索の場合、text
パッケージ implements a Boyer-Mooreベースのアルゴリズム 。これは、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