2013-10-06 90 views
2

我必須編寫一個函數(不使用預先加載的函數)來決定某個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) | 
+1

想象你的函數是在'(X:XS)'在列表中的一些隨機點:什麼其他信息或狀態除了頭部和尾部之外,你還需要確定你是否應該在那個時候返回「False」? – jberryman

+1

如果你想要另一個解決這個問題的辦法,記住你在這裏真正計算的是列表的派生符號。您可以輕鬆編寫一個函數來計算連續元素之間的差異,然後檢查值的符號。 – bheklilr

回答

3

我會在開發它時嘗試向您解釋一些代碼。這個問題顯然可以分爲兩部分:檢測列表的增加部分和列表的減少部分。在Haskell中使用列表的關鍵思想是你(如果你還沒有空的列表),總是看頭部的列表和尾部,你通常會嘗試通過該順序列表。

因此,讓我們編寫一個函數來檢測列表是否首先非嚴格地減少。當然有幾種方法可以做到這一點。讓我們嘗試一種沒有額外參數的遞歸方法。你已經有了一個好的開始

dec :: [Int] -> Bool 
dec [] = True 

現在讓我們繼續模式匹配。下一個最大的不是空的列表是一個元素的列表,它顯然總是遞減:

dec [x] = True 

下一步很有趣。如果我們有開頭兩個元素(xy)(可能更多)的列表,然後在列表中取消遞減,顯然x >= y需要持有,而且剩下的表,從y,需要被降低。這樣就足夠了,我們只需要把它寫出來

dec (x:y:rest) = x >= y && dec (y:res) 

而那就是它!

現在你的鍛鍊功能,在哪裏可以做同樣的事情。唯一的區別是,一旦名單未能在增加,我們允許檢查列表可能從這個角度上減少:

​​

我希望我是怎麼來編寫代碼可以幫助你解釋你的下一個練習。另外請注意,還有很多其他更有效的解決方法。

+0

非常感謝你的出色解釋,這真的很有幫助! – haskelllearner

4

只是爲了好玩,我以爲我會一起解決一個非常不同的味道。試想一下,當數字減少時,我們有一個字符串,而不是數字列表,,當他們保持不變時,或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

+1將我介紹給正則表達式應用程序。 –