我需要找到矩陣中最小的元素。 我有一個解決方案,但它並不完美。查找矩陣中的最小元素[[Int]]
type Matrix = [[Int]]
matMin :: Matrix -> Int
matMin [] = 99999999999
matMin (xs:xss) = minimum xs `min` matMin xss
任何人都可以給我一個更好的解決方案的提示嗎?
我需要找到矩陣中最小的元素。 我有一個解決方案,但它並不完美。查找矩陣中的最小元素[[Int]]
type Matrix = [[Int]]
matMin :: Matrix -> Int
matMin [] = 99999999999
matMin (xs:xss) = minimum xs `min` matMin xss
任何人都可以給我一個更好的解決方案的提示嗎?
我能想到的最簡單的事情就是matMin = minimum . concat
看一看map
功能。一矩陣的最小距離各行的最小值中的最小值:
Prelude> :t minimum . map minimum
minimum . map minimum :: Ord c => [[c]] -> c
稍微調整了您的代碼,這將避免使用該硬編碼值的版本:
type Matrix = [[Int]]
matMin :: Matrix -> Int
matMin [] = error "min is undefined for 0x0 matrix"
matMin [xs] = minimum xs
matMin (xs:xss) = minimum xs `min` matMin xss
或用您的方法粘結,您可以改用maxBound
(因爲Int
是Bounded
)。
matMin :: Matrix -> Int
matMin [] = maxBound
matMin (xs:xss) = minimum xs `min` matMin xss
這實際上看起來像一個摺疊。
matMin = foldl' (acc x -> minimum x `min` acc) maxBound
或者,如果你想獲得一點點無謂
matMin = foldl' (flip (min . minimum)) maxBound
-- or if you don't like the flip
matMin = foldr (min . minimum) maxBound
注意這種模式適用於任何矩陣「摺疊」工作。
matFoldr :: (b -> c -> c) -- how to merge the accumulator with the result of mergeCells
-> ([a] -> b) -- how to merge a row of cells
-> c -- a starting accumulator value
-> [[a]] -- the matrix to fold over
-> c
matFoldr mergeRows mergeCells start = foldr (mergeRows . mergeCells) start
matMin = matFoldr min minimum maxBound
matMax = matFoldr max maximum minBound
matSum = matFoldr (+) sum 0
matProduct = matFoldr (*) product 1
如果我們真的想要,我們甚至可以做到這一點,所以您不必指定要使用哪個列表操作。
matEasyFold mergeRows start = matFoldr mergeRows mergeCells start
where mergeCells = foldr mergeRows start
matMin = matEasyFold min maxBound
matSum = matEasyFold (+) 0
-- etc
非常感謝你:-P我解決了容易得多,但它是從米哈伊
matMin :: Matrix -> Int
matMin xss = minimum(map minimum xss)
感謝您的幫助非常相似的答案。
事實上,除了Mihai在[pointfree form](http://www.haskell.org/haskellwiki/Pointfree)中表達它之外,它是一樣的。 – MatrixFrog