How can you just flash through a two-dimensional grid?

Using, for example, census lightning, you can go through one-dimensional space. Is there an equally elegant and efficient way of coding the concept of walking (without a picture) through a two-dimensional grid?

+4
source share
1 answer

The real question is: what do you want to go through the 2D grid?

Is it random access or some kind of template? Problems with dynamic programming are often modeled as moving a 2D grid, but this is not random access, it is pretty with the drawing. And the patterns we can work with.


For example, consider a problem finding the editing distance between two lines where we are given:

-- the cost of replacing one character with another
charEditCost :: Char -> Char -> Int

-- the cost of inserting a character
charInsertCost :: Char -> Int

:

editDistance [] [] = 0
editDistance (a:as) [] = editDistance as [] + charInsertCost a
editDistance [] (b:bs) = editDistance [] bs + charInsertCost b
editDistance (a:as) (b:bs) = minimum
  [ editDistance as bs + charEditCost a b
  , editDistance (a:as) bs + charInsertCost b
  , editDistance as (b:bs) + charInsertCost a
  ]

- , editDistance as bs - , editDistance (a:as) bs, - editDistance as (b:bs).

:

editDistance as bs = last . last $ grid where 
  firstRow j = grid !! 0 !! (j-1) + charInsertCost (as!!j)
  firstCol i = grid !! (i-1) !! 0 + charInsertCost (bs!!i)
  innerCel i j = minimum
    [ grid !! (i-1) !! (j-1) + charEditCost (as!!j) (bs!!i)
    , grid !! i !! (j-1) + charInsertCost (as!!j)
    , grid !! (i-1) !! j + charInsertCost (bs!!j)
    ]
  grid = (          0 : [ firstRow j   | j <- [1..length as] ] ) : 
       [ ( firstCol i : [ innerCel i j | j <- [1..length as] ] ) | i <- [1..length bs ]

, !! - O (n). , , ; , . , , , .

, fibs = 1 : 1 : zipWith (+) fibs (tail fibs) fibs!!(i-1) fibs!!(i-2) fibs!!i, .

editDistance as bs = last . last $ grid where
  firstRow = scanl (+) 0 $ map charInsertCost as
  firstCol = scanl (+) 0 $ map charInsertCost bs
  grid = ( 0 : firstRow ) : zipWith3 mkRow bs firstCol grid
  mkRow b firstCel lastRow = let thisRow = firstCel : zipWith4 (mkCel b) as thisRow lastRow (tail lastRow) in thisRow
  mkCel b a leftCel aboveLeftCel aboveCel = minimum
    [ aboveLeftCel + charEditCost b a
    , aboveCel + charInsertCost b
    , leftCel + charInsertCost a
    ]

2D- , .

+6

Source: https://habr.com/ru/post/1612097/


All Articles