您好我尝试在Haskell中实现KMP字符串搜索算法。但是当我尝试运行kmp函数时,它只会说"非详尽的模式"这个功能。无论我多么努力纠正它。我以为我的每一个可能的结果都是隐蔽的。也许我只是失明但我希望有人能在这里帮助我。:
prefix :: String -> [Int]
prefix p = hprefix p p 0
hprefix :: String -> String -> Int -> [Int]
hprefix [] (i:is) int = []
hprefix (p:ps) (i:is) int | (length(i:is)) - (length(p:ps)) == 0 = 0:(hprefix ps (i:is) 0)
| p == (head(drop (int) (i:is))) = (int+1):(hprefix ps (i:is) (int+1))
| p == i = 1:(hprefix ps (i:is) 1)
| otherwise = 0:(hprefix ps (i:is) 0)
hkmp :: String -> String -> [Int]
hkmp p [] = error "leerer Text"
hkmp [] t = error "leeres Pattern"
hkmp p t = kmp p p (take (length p) t) t t
kmp :: String -> String -> String -> String -> String -> [Int]
kmp p (a:as) (b:bs) (t:ts) o | o == [] = error "leerer Text"
| p == [] = error "leeres Pattern"
| (length p) > (length o) = error "Pattern größer als Text"
| (t:ts) == [] = []
| (a:as) == [] = ((length(o)) - (length (t:ts))):(kmp p p (take (length p) (drop (length p) (t:ts))) (drop (length p) (t:ts)) o)
| (b:bs) == [] = []
| a == b = (kmp p as bs (t:ts) o)
| (head(drop ((length p) - (length (a:as))) (prefix p))) == 0 = (kmp p p (take (length p) ts) ts o)
| otherwise = (kmp p (drop (head(drop ((length p) - (length (a:as))) (prefix p))) p) (take (length p) (drop (head(drop ((length p) - (length (a:as))) (prefix p))) (t:ts))) (drop (head(drop ((length p) - (length (a:as))) (prefix p))) (t:ts)) o)
非常感谢!
答案 0 :(得分:2)
使用-fwarn-incomplete-patterns
或-Wincomplete-patterns
,GHC会告诉您需要添加哪些模式以避免此错误:
test.hs:5:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘hprefix’:
Patterns not matched:
[] [] _
(_:_) [] _
|
5 | hprefix [] (i:is) int = []
| ^^^^^^^^^^^^^^^^^^^^^^^^^^...
test.hs:17:1: warning: [-Wincomplete-patterns]
Pattern match(es) are non-exhaustive
In an equation for ‘kmp’:
Patterns not matched:
_ [] _ _ _
_ (_:_) [] _ _
_ (_:_) (_:_) [] _
|
17 | kmp p (a:as) (b:bs) (t:ts) o | o == [] = error "leerer Text"
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
答案 1 :(得分:0)
你的遗失模式是之前守卫。 (a:as)
之类的内容无法与[]
匹配,即使您为此提供了警卫。你应该写得更像:
kmp _ _ _ _ [] = error "leerer Text"
kmp [] _ _ _ _ = error "leeres Pattern"
kmp p _ _ _ o | (length p) > (length o) = error "Pattern größer als Text"
kmp _ _ _ [] _ = []
kmp _ _ _ [] _ = []
kmp p [] _ t o = ((length o) - (length t))):(kmp p p (take (length p) (drop (length p) t)) (drop (length p) t) o)
kmp _ _ [] _ _ = []
kmp p (a:as) (b:bs) t o | a == b = (kmp p as bs t o)
kmp p (a:as) (b:bs) (t:ts) o | (head(drop ((length p) - (length (a:as))) (prefix p))) == 0 = (kmp p p (take (length p) ts) ts o)
kmp p a _ t o = (kmp p (drop (head(drop ((length p) - (length a)) (prefix p))) p) (take (length p) (drop (head(drop ((length p) - (length a)) (prefix p))) t)) (drop (head(drop ((length p) - (length a)) (prefix p))) t) o)
虽然你应该考虑进一步打破这个问题。这真的很难理解。
答案 2 :(得分:0)
很明显,您的hprefix
和kmp
功能并非全部,因此并非详尽无遗。
要了解原因,请回忆kmp
的第一个(也是唯一的)等式:
kmp p (a:as) (b:bs) (t:ts) o = ...
在这里,您定义kmp
强制第二,第三和第四个参数为非空字符串。因此,为了总计kmp
,您必须覆盖这些丢失的案例,例如,将另一个等式添加到kmp
的模式匹配定义中,该定义将捕获这些字符串为空的情况:
kmp p s1 s2 s3 o = ...
编译器只是声明如果在上面提到的地方用空字符串调用kmp
,程序可能会在运行时崩溃,因为它没有定义。