2011-11-25 88 views
3

我需要找到矩阵中最小的元素。 我有一个解决方案,但它并不完美。查找矩阵中的最小元素[[Int]]

type Matrix = [[Int]] 
matMin :: Matrix -> Int 
matMin [] = 99999999999 
matMin (xs:xss) = minimum xs `min` matMin xss 

任何人都可以给我一个更好的解决方案的提示吗?

回答

10

我能想到的最简单的事情就是matMin = minimum . concat

9

看一看map功能。一矩阵的最小距离各行的最小值中的最小值:

Prelude> :t minimum . map minimum 
minimum . map minimum :: Ord c => [[c]] -> c 
4

稍微调整了您的代码,这将避免使用该硬编码值的版本:

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(因为IntBounded)。

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 
0

非常感谢你:-P我解决了容易得多,但它是从米哈伊

matMin :: Matrix -> Int 
    matMin xss = minimum(map minimum xss) 

感谢您的帮助非常相似的答案。

+0

事实上,除了Mihai在[pointfree form](http://www.haskell.org/haskellwiki/Pointfree)中表达它之外,它是一样的。 – MatrixFrog