在一个矩阵[[Int]]中找到最小的元素

3

我需要找到矩阵中最小的元素。 我有一个解决方案,但不是完美的。

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

有没有人能给我一个更好的解决方案的提示?

4个回答

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 我解决得更容易,但它与Mihai的答案非常相似

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

感谢您的帮助。


实际上,除了 Mihai 用 无参考形式 表达之外,它是相同的。 - Tyler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接