2015-10-06 19 views
1

對於任務,我被要求使用列表理解重新編寫以下函數。該函數獲取整數列表和一個整數數字a,並返回列表中包含數字a的整數數量。Haskell - 使用列表理解返回包含數字的整數數

例如

count [102,41,256] 2 

應該返回2

count [98,4,376] 2 

應該返回0

這是我對非列表解析功能:

split :: Int -> [Int] 
split 0 = [] 
split x = split (div x 10) ++ [rem x 10] 

checkDigits :: [Int] -> Int -> Int 
checkDigits [] y = 0 
checkDigits (x:xs) y 
    | x == y = 1 + (checkDigits xs y) 
    | otherwise = checkDigits xs y 

count :: [Int] -> Int -> Int 
count [] a = 0 
count (x:xs) a 
    | (checkDigits (split x) a) > 0 = (checkDigits (split x) a) + (count xs a) 
    | otherwise = count xs a 

拆分將在整數並返回列表中的整數

split 321 will return: [3,2,1] 

checkDigits計數的時間,一個數字都顯示在一個整數(這是爲了解決一個錯誤的位置count [22] 2將返回爲0時,它應該返回2

e.g. the digit '2' appears 4 times in the list [2,65,42,22] 
在數

最後數我們使用checkDigits檢查x中的任何數字是否等於a,如果此數字大於0(1或更多等於a),則添加找到的數字位數並再次調用。

我是新來列出內涵和只設法得到它的工作,如果在列表中的數等於a

countD :: [Int] -> Int -> Int 
countD intL a = length [y | y <- intL, y == a] 

這裏countD [2,3,4,22] 2回報1升如何更改我有這麼它將返回3(因爲列表中有3 2)。

回答

3

您的問題對count函數應該精確執行的操作不明確。在開始的時候你說

的整數,其中包含數字

,而列表中的號碼以後你說

count [22] 2/.../應該返回2

這是包含數字2[22]整數數量 - 有在該列表中只有一個整數,所以你應該返回1,不管這個整數包含的事實數字2兩次。

因此,我在下面提供了兩種可能性的解決方案。


對於第一種可能性,這個解決方案是我能想出的最短:

-- these are optional 
type Digit = Int 
type Number = Int 
type Count = Int 

count :: [Number] -> Digit -> Count 
count xs d = sum [count' x | x <- xs] -- same as `sum $ map count' xs` 
    where count' x = if d' `elem` show x then 1 else 0 
     d':[] = show d 

但是,如果第二個可能性是確實是正確的,count [22] 2應該返回2,然後更改count'幫手功能:

count :: [Number] -> Digit -> Count 
count xs d = sum [count' x | x <- xs] 
    where count' i = length $ filter (== d') (show i) 
     d':[] = show d 
+0

道歉我盡力解釋它。正確的方法是它應該計算實際數字在列表中出現的次數。例如 count [102,45,256,24] 2會返回3.這是因爲數字「2」在列表中出現了三次。 –

+0

[更新]我實際上重新閱讀了簡要內容,並意識到我誤解了它所說的內容,並且您的第一點實際上是正確的。對此抱歉。你也可以解釋定義數字,數字和計數爲Int類型的好處嗎?你能不能只用count :: [Int] - > Int - > Int? –

+1

是的,你是對的:你可以使用'[Int] - > Int - > Int'這也是爲什麼我在別名之上添加註釋' - 這些是可選的':)它們只是爲了可讀性, Int'不是很具描述性。在諸如Agda或Idris這樣的語言中,你會使用更多的約束(並因此描述)數據類型,而不僅僅是類型別名:返回類型將是'Nat',而'Digit'將會是'Fin 10'(這是上限爲10的'Nat');它甚至可以返回一個證明返回值是<= length xs'等:) –

3

使用checkDigitssplitcountD。這是你如何計算整數包含數字(二,在你的例子)數量:

countD intL a = length [y | y <- intL, (checkDigits (split y) a) > 0] 

這裏是你如何計算的總次數出現的數字(三個你的例子):

countD intL a = sum [checkDigits (split y) a | y <- intL] 
+0

圖例,感謝您的幫助 –

4

我能做的最好的。 如果有人向我展示瞭如何傳遞整數 2數字作爲參數而不是硬編碼 ,我將不勝感激。

感謝Erik的回答。

countDigits :: [Int] -> Int -> Int 
countDigits xs d = sum [1 | n <- (concat . map show) xs, n == d'] 
    where d':[] = show d 
+3

'countDigits xs d = sum [1 | n < - concat $ map show xs,n == d']其中d':[] =顯示d',如果您想傳入數字並將其從'Int'轉換爲'Char',如同我的解決方案。 –

+0

謝謝Allik,我花了一分鐘才明白。 – Ori

+0

好吧,它只是'd'= head $ show d',但很有趣。 –