我必須編寫一個函數(不使用預先加載的函數)來決定某個Ints列表是否爲三角形,並且通過三角形表示它是否增加到一定數量然後減小,例如:Haskell中的三角列表?
[2,4,5,7,4,3],還有:[],[1],[1,1],[1,2,3],[3,2,1],[1,2 ,2],[2,2,1](所以不嚴格增加和減少)
我想出了這一點,但我不知道下一步該怎麼做,任何意見表示讚賞:
ex :: [Int] -> Bool
ex [] = True
ex (x:xs) |
我必須編寫一個函數(不使用預先加載的函數)來決定某個Ints列表是否爲三角形,並且通過三角形表示它是否增加到一定數量然後減小,例如:Haskell中的三角列表?
[2,4,5,7,4,3],還有:[],[1],[1,1],[1,2,3],[3,2,1],[1,2 ,2],[2,2,1](所以不嚴格增加和減少)
我想出了這一點,但我不知道下一步該怎麼做,任何意見表示讚賞:
ex :: [Int] -> Bool
ex [] = True
ex (x:xs) |
我會在開發它時嘗試向您解釋一些代碼。這個問題顯然可以分爲兩部分:檢測列表的增加部分和列表的減少部分。在Haskell中使用列表的關鍵思想是你(如果你還沒有空的列表),總是看頭部的列表和尾部,你通常會嘗試通過該順序列表。
因此,讓我們編寫一個函數來檢測列表是否首先非嚴格地減少。當然有幾種方法可以做到這一點。讓我們嘗試一種沒有額外參數的遞歸方法。你已經有了一個好的開始
dec :: [Int] -> Bool
dec [] = True
現在讓我們繼續模式匹配。下一個最大的不是空的列表是一個元素的列表,它顯然總是遞減:
dec [x] = True
下一步很有趣。如果我們有開頭兩個元素(x
和y
)(可能更多)的列表,然後在列表中取消遞減,顯然x >= y
需要持有,而且剩下的表,從y
,需要被降低。這樣就足夠了,我們只需要把它寫出來
dec (x:y:rest) = x >= y && dec (y:res)
而那就是它!
現在你的鍛鍊功能,在哪裏可以做同樣的事情。唯一的區別是,一旦名單未能在增加,我們允許檢查列表可能從這個角度上減少:
我希望我是怎麼來編寫代碼可以幫助你解釋你的下一個練習。另外請注意,還有很多其他更有效的解決方法。
非常感謝你的出色解釋,這真的很有幫助! – haskelllearner
只是爲了好玩,我以爲我會一起解決一個非常不同的味道。試想一下,當數字減少時,我們有一個字符串,而不是數字列表,,當他們保持不變時,或G
,當他們變得更大時,我們有一個L
。然後是三角形意味着測試該字符串是否使用正規語言[LE]*[GE]*
。所以這就是我們在這個解決方案中所要做的:編寫一個正則表達式並檢查數字的摘要是否與它匹配。我使用的是regex-applicative,但如果你喜歡,你可以使用你最喜歡的正則表達式庫。
{-# LANGUAGE NoMonomorphismRestriction #-}
import Data.Maybe
import Text.Regex.Applicative
triangular = many (sym LT <|> sym EQ) *> many (sym GT <|> sym EQ)
summarize xs = zipWith compare xs (tail xs)
ex = isJust . match triangular . summarize
我們可以嘗試在所有的例子ghci的:
*Main> map ex [[2,4,5,7,4,3], [], [1], [1, 2, 3], [3, 2, 1], [1, 2, 2], [2, 2, 1]]
[True,True,True,True,True,True,True]
*Main> ex [2,3,4,3,2,3,4] -- plus one I made up to check it's not const True
False
+1將我介紹給正則表達式應用程序。 –
想象你的函數是在'(X:XS)'在列表中的一些隨機點:什麼其他信息或狀態除了頭部和尾部之外,你還需要確定你是否應該在那個時候返回「False」? – jberryman
如果你想要另一個解決這個問題的辦法,記住你在這裏真正計算的是列表的派生符號。您可以輕鬆編寫一個函數來計算連續元素之間的差異,然後檢查值的符號。 – bheklilr