在Haskell中修改数组并记住索引

时间:2012-03-21 13:51:11

标签: arrays haskell

我需要对子数组进行转换,并且可能需要在子数组的子数组上进行转换,依此类推。

在Haskell中有直观的方法吗,比如定义一个子阵列或类似的东西?我在“对haskell的一个温和的介绍”中阅读了关于数组的部分,并没有解决它,我很难找到一种方法来实现它。

用于维基百科上描述的here匈牙利算法的实现。

所以到目前为止我做了以下事情:

import Array

step1 :: (Ord a , Num a) => Array (Int,Int) a -> Array (Int,Int) a
step1 a      = a // [ ((i,j), f (i,j) ) | (i,j) <- range (bounds a) ] where
    f (i,j)  = a!(i,j) - minRow i
    minRow i = minimum [ a!(i,j) | j <- [1..(snd . snd . bounds) a] ]

step2 :: (Ord a , Num a) => Array (Int,Int) a -> Array (Int,Int) a
step2 a      = a // [ ((i,j), f (i,j) ) | (i,j) <- range (bounds a) ] where
    f (i,j)  = a!(i,j) - minCol j
    minCol j = minimum [ a!(i,j) | i <- [1..(fst . snd . bounds) a] ]

问题是我不知道如何实施第3步和第4步,继续子矩阵上的程序,以防止解决方案不可用。

1 个答案:

答案 0 :(得分:1)

我找到了一种解决方法,尽管这有点像黑客。它只适用于2D数组,即Array (Int,Int) Int类型的数组。这是我做的:

import Data.Array
import Control.Applicative

updateSubArr :: [Int] -> [Int] -> (Array (Int,Int) Int -> Array (Int,Int) Int)
                      -> Array (Int,Int) Int -> Array (Int,Int) Int
updateSubArr rows cols f arr    = arr // (zip [(i,j) | i <- rows, j <- cols ]
                                [ fSubArr!i | i <- range $ bounds subArr ]) where
fSubArr = f subArr
subArr  = subArray cols rows arr

subArray rows cols arr  = subArr where
    js      = length cols
    is      = length rows
    subArr      = array subBounds $ zip (range subBounds)
                             [ arr!(i,j) | i <- rows, j <- cols ]
    subRange    = range subBounds
    subBounds   = ((1,1),(is,js))

这可以用于普通Array a b吗?