2014-10-28 45 views
0

當我使用sub_string("abberr","habberyry")時,它返回True,顯然它應該是False。該函數的要點是在第二個參數中搜索第一個參數。任何想法有什麼不對?Haskell子串測試

sub_string :: (String, String) -> Bool 
sub_string(_,[]) = False 
sub_string([],_) = True 
sub_string(a:x,b:y) | a /= b = sub_string(a:x,y) 
        | otherwise = sub_string(x,y) 
+1

(在Haskell,最好採取用空格隔開,而不是通過一對作爲參數傳遞兩個參數。) – AndrewC 2014-10-28 13:00:20

回答

3

首先,您需要切換前兩行。 _將與[]匹配,這在你匹配的時候很重要,比如substring "abc" "abc"。其次,Haskell習慣於用兩個參數來寫一個函數,而不是一個帶有一對參數的函數。所以你的代碼應該開始:

substring :: String -> String -> Bool 
substring [] _ = True 
substring _ [] = False 
substring needle (h : aystack) 
    | ... 

現在我們來看看這兩個列表都不是空的棘手情況。下面是用遞歸上substring as bs問題:你會得到像​​結果是的"axbxcx"(因爲​​子字符串匹配'a'第一,然後將尋找"bc"在字符串的其餘部分;然後串算法將跳過的'x'到。尋找在"bxcx""bc",這將匹配'b'"xcx"尋找"c",這將返回True

而不是你的條件必須更徹底。如果你願意使用功能從Data.List這就是:

| isPrefixOf needle (h : aystack) = True 
    | otherwise = substring needle aystack 

否則,你需要編寫自己的isPrefixOf,例如:

isPrefixOf needle haystack = needle == take (length needle) haystack 
+2

「(h:aystack)」 - 非常聰明。 – user2407038 2014-10-28 16:17:34

+0

我完全從PHP中竊取了它,它們引入了名爲'$ needle'和'$ haystack'的參數來顯示參數的順序。 Haskell的習慣可能會改爲'輸入Needle = String'等。 – 2014-10-28 16:34:12

5

讓我給你提示,爲什麼它不工作:

  • 的功能會消耗在初始階段投入刺「abber」和「habber」。
  • 現在剩下「r」和「yry」了。

而「r」是「yry」的子集。所以它返回True。爲了說明你的問題的更簡單的例子:

*Main> sub_string("rz","rwzf") 
True 
+0

會如何我去解決這個問題? – Summer 2014-10-28 11:02:29

2

由於思碧已經指出的那樣,序列您的功能測試。回顧上一個練習,可能是isPrefixof(hackage documentation),這只是一個奇怪的說startsWith,看起來非常類似於你寫的功能。 如果這不是以前的練習,現在就做!

然後在isPrefixOf方面寫sub_string

sub_string (x, b:y) = isPrefixOf ... ?? ??? 

填寫的點和 「?」你自己。