2017-09-01 27 views
0

我是Haskell的新手,我目前在學校學習它。我得到了一個學校任務,我必須解碼包含特定模式的消息,但我不知道如何執行此操作。Haskell - 用模式解碼消息

該模式看起來像這樣:如果一個字母有一個輔音,後面跟着字符'o',然後再次跟隨着相同的輔音,它應該替換那個子字符串(「XoX」,其中X是一個輔音)只有輔音。例如,如果我解碼字符串「hohejoj」它應該返回「hej」。對不起,如果我解釋這很糟糕,但我想你明白。

這是我迄今(但它不工作)代碼:¨

karpsravor :: String->String 
karpsravor s = karpsravor_help s "" 
    where karpsravor_help s res 
      |s == "" && (last res) == 'o' = (init res) 
      |s==""=res 
      |otherwise = karpsravor_help (drop 3 s) (res ++ (consDecode (take 3 s))) 

consDecode :: String->String 
consDecode a 
    |(length a) < 3 = "" 
    |a == [(head a)]++"o"++[(head a)] = [(head a)] 
    |otherwise = a 

的代碼是完全壞了,寫得不好(啞方法),但我對如何沒有別的想法解決此問題。請幫忙!

+1

像'head,tail'這樣的函數是不完整的,如果忘記檢查是否空虛,可能會導致程序崩潰。如果可能,應避免使用它們。它們不是慣用的Haskell,它支持模式匹配,因爲它是安全的。與模式匹配相比,長度a <3'也是低效的。 – chi

回答

2

Pattern match查找「o」的出現次數。即,使用

karpsravorhelp (a:'o':b:rest) res = ...

你不能在上面a:'o':a:rest,你不能平等的模式匹配;你需要使用保護,以確保a == b

karpsravorhelp (a:'o':b:rest) res | a == b = ... | otherwise = ...

您還必須確保ab都是輔音字母,這將只是第一個後衛的「和」條件。對於otherwise條件,請確保遞歸調用(b:rest),因爲您可能有類似a:'o':b:'o':b:...的內容。

同時一定要匹配其他兩種模式:

  1. 空列表,[]
  2. x:rest,必須在上面的圖案後去;這樣,它會首先嚐試匹配a:'o':b:rest模式,如果不在那裏,就拿下一個字母。
1

一種方法是使用unfoldrData.List。您可以使用case表達式在a : 'o' : b : rest上進行模式匹配,然後檢查ab是否相等,而不是使用後衛|的元音。然後只包括模式不匹配時的基本情況。

notVowel :: Char -> Bool 
notVowel = (`notElem` "aeiouAEIOU") 

karpsravor :: String -> String 
karpsravor = unfoldr $ \str -> case str of 
    a : 'o' : b : rest 
     | a == b && notVowel a -> Just (a, rest) 
    a : rest     -> Just (a, rest) 
    ""       -> Nothing